[Haskell-beginners] Fwd: deep seq and bang patterns

Daniel Fischer daniel.is.fischer at googlemail.com
Tue Dec 25 20:37:09 CET 2012


On Dienstag, 25. Dezember 2012, 20:00:18, Emmanuel Touzery wrote:
> Hello,
> 
> On Tue, Dec 25, 2012 at 3:39 PM, Daniel Fischer <
> 
> daniel.is.fischer at googlemail.com> wrote:
> > Defining TvShow with strict fields for title, startTime and summary
> > makes
> > sure
> > these fields are evaluated (to WHNF, but in case of `Data.Text`, that
> > means fully evaluated) **when the TvShow value is evaluated to WHNF**.
>
> how do I know what does "evaluated to WHNF" means for every possible type?

For non-function types, it means evaluate until the outermost constructor is 
known. For function types (which have no constructors), it means evaluating to 
the outermost lambda.

> 
> For instance, what does that mean for "String"?

String is a list, so there it means evaluate until it is known whether the 
value is [] or (_:_).

In particular, characters (or generally list elements) are only evaluated if 
that is necessary to determine whether the list is empty or not.

If `dropWhile isSpace someString` is evaluated to WHNF, the characters in 
someString must be evaluated until the first non-space character is found (or 
the end of someString is reached, or a _|_ is reached) since that is necessary 
to find the outermost constructor. So evaluating

dropWhile isSpace [' ' .. ]

to WHNF produces ('!':_) and not only (_:_)

> What does that mean for "Maybe String"?

Find out whether it's a `Just someThing` or `Nothing`.

Again, in the case of a `Just someThing`, the someThing is only evaluated if 
that's necessary to find out whether it's a `Just` at all.

> 
> If I want the field to be fully evaluated, is !(Maybe String) enough or
> should I even do !(Maybe !String) or something more?

You can't have something like

Maybe !String

`!String' is not a type, so it's not an allowed argument for `Maybe'.

A field `field :: !(Maybe String)' would only force evaluation of the `Maybe' 
constructor when the containing value is evaluated, the String in a `Just' 
would still remain completely unevaluated (unless that is necessary to find 
out whether the `Maybe String' value is a `Just').

You can define a strict version of `Maybe`,

data SMaybe a
    = SJust !a
    | SNothing

and have a field `field :: !(SMaybe String)'. But that would still only 
evaluate the String to WHNF, so `SJust (undefined : undefined)' is still 
possible.

If you want complete evaluation, you need to recur through every type adding a 
constructor layer, until you reach a function type or a base case 
(enumerations

data Foo
    = Bar
    | Baz
    | Quux

and wrappers of primitive types like

data Int = I# Int#

[for GHC]).

> 
> Any source of information where I can read about this in depth would be
> welcome (I have yet to read Real World Haskell, maybe it's covered there?).

I don't know to what depth it is covered in RWH, it must be covered in some 
depth there.

And there's of course the invaluable and authoritative language report

http://www.haskell.org/onlinereport/haskell2010/

Cheers,
Daniel



More information about the Beginners mailing list