Differences in pattern matching syntax?

Claus Reinke claus.reinke at talk21.com
Thu Jan 15 19:29:08 EST 2009

>   antecedent :: Rule -> Expression
>   antecedent r = case r of
> ..
>                   Gc{} -> let x = grspe r in r `seq` Tm r

This looks wrong. The idea was to replace

    Tm (grspe r)

(where the selection expression is put into Tm unevaluated) with

    let x = grspe r 
    in x `seq` Tm x

ie, bind the selected expression to 'x', then force 'x' to be
evaluated before putting it in 'Tm x'. Alternatively, 

    Tm $! (grspe r)

should do the same forcing. However, either variant will force
evaluation of the selected field as well, not just evaluation of the

Consider this small example:

    data T x = T {field :: x}
    f (T x) = Just x
    g tx = Just (field tx)
    h tx = Just $! (field tx)

The three functions 'f', 'g', and 'h' are different, as can be seen (in
part) by evaluating 

    *Main> Data.Maybe.isJust $ f (T undefined)
    *Main> Data.Maybe.isJust $ g (T undefined)
    *Main> Data.Maybe.isJust $ h (T undefined)
    *** Exception: Prelude.undefined

    f: passes the 'field' 'x' unchanged
    g: passes the whole record, wrapped in a selection
    h: passes the 'field', after evaluating it

The extra wrapping in 'g' corresponds to where Simon suspects
your difference in memory behaviour comes from (by the time the
wrappers get evaluated, there are too many of them to fit on the 
stack). Neither 'g' nor 'h' are equivalent to 'f', but the equivalent
of 'h' (forcing the record selection before putting it in another
constructor) might fit your needs better than the equivalent of 'g'.


>   antecedent :: Rule -> Expression
>   antecedent r = case r of
>                   Gc{} -> let x = grspe r in r `seq` Tm x

This is forcing 'r', not the selection 'x' from 'r'.

More information about the Glasgow-haskell-users mailing list