views:

355

answers:

3

I execute the next code:

(take 10) $! [1,2..]

What is it ? I thought, ghc will yield a termination, beacause i say "evaluate [1,2..] force". But I got the result "[1,2,3,4,5,6,7,8,9,10]".

+1  A: 

Did you type something wrong? It works for me with or without parentheses, under GHCi 6.8.2...

GHCi, version 6.8.2: http://www.haskell.org/ghc/  :? for help
($Loading package base ... linking ... done.
Prelude> take 10 $! [1..]
[1,2,3,4,5,6,7,8,9,10]
Prelude> (take 10) $! [1..]
[1,2,3,4,5,6,7,8,9,10]
Prelude> (take 10) $! [1,2..]
[1,2,3,4,5,6,7,8,9,10]
Mark Rushakoff
The My GHC give me the same result as your ghc. But this is result not satisfy me. I want give a terminate.When used with a curried function with multiple arguments, strict application can be used to force top-level evaluation of any combination of arguments.For example, if f is a curried function with two arguments, an application ofthe form f x y can be modified to have three different behaviours:(f $! x ) y forces top-level evaluation of x(f x) $! y forces top-level evaluation of y(f $! x) $! y forces top-level evaluation of x and y
Anton
+3  A: 

The forced evaluation will only ensure its argument [1,2..] isn't bottom. [1,2..] matches (1:_), so it isn't bottom, and the computation will go on as expected, returning [1,2,3,4,5,6,7,8,9,10].

Not sure where you got that single 1 result from; would you mind copy-pasting an excerpt of a GHCi session?

JB
unfortunately, new user do not post images.
Anton
http://img111.imageshack.us/img111/651/66718556.jpg
Anton
Surely for two lines of text, you *could* have copied them as text ;)
JB
+6  A: 

So you expect the list to be fully evaluated. ($!) is implemented in terms of seq, and seq "only" evaluates to head normal form according to the docs. It'll only make a difference if the value is undefined:

Prelude> take 0 undefined
[]
Prelude> take 0 $! undefined
*** Exception: Prelude.undefined

A function is strict in its argument if

f undefined = undefined

This does not imply that the argument is fully evaluated in an eager fashion. What you want is something like DeepSeq.

GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling DeepSeq          ( deepSeq.lhs, interpreted )
Ok, modules loaded: DeepSeq.
*DeepSeq> take 1 $!! [1,2,undefined]
*** Exception: Prelude.undefined
*DeepSeq>

Your example with $!! from DeepSeq runs forever.

Rüdiger Hanke
Could you give me this doc ? )
Anton
I just meant the doc of "seq :: a -> b -> b" which says "Evaluates its first argument to head normal form, and then returns its second argument as the result."
Rüdiger Hanke
Thank you very much!
Anton