16

I read that the $! operator forces strict evaluation. So why does this still work?

Prelude> take 10 $! repeat 1
[1,1,1,1,1,1,1,1,1,1]

I was expecting ghc to grind away forever trying to evaluate the infinite list of 1's.

knick
  • 941
  • 8
  • 17

1 Answers1

26

$! forces its second argument to weak head normal form, which basically means it evaluates its argument's outermost constructor. So in your case, it will not force the evaluation of the whole list, but only evaluate the outermost (i.e. first) : constructor.

There is a good explanation of normal form vs WHNF at Haskell: What is Weak Head Normal Form? .

Note that if you forced evaluation of the whole list (e.g. using the $!! operator from the Control.DeepSeq module), your program would not terminate:

λ: import Control.DeepSeq (($!!))
λ: take 10 $!! repeat 1
^C
Community
  • 1
  • 1
fjh
  • 12,121
  • 4
  • 46
  • 46
  • The linked SO thread on Weak Head Normal Form is a great read, thanks! – knick May 12 '14 at 15:28
  • 1
    Note also that `take n`, for `n > 0`, has to force the list to WHNF anyway, so `take 10 $! repeat 1` is operationally the same as `take 10 $ repeat 1`. – Luis Casillas May 14 '14 at 00:22