I put these definitions in a file:
x = 'a' : 'b' : 'c' : []
y = ['a', 'b', 'c']
(It is important to define those in a file, not in GHCi, because in the latter case things become way more weird, but that’s another question.)
Now, I load this file in GHCi and:
λ> :sprint x
x = _
λ> :sprint y
y = _
λ> seq x ()
()
λ> seq y ()
()
λ> :sprint x
x = 'a' : _
λ> :sprint y
y = "abc"
What is going on here? I understand what happens in the case of x
, that’s exactly what I expected. But what about y
?
What I see seems to contradict section 3.7 of the Report, which says:
Translation: The following identity holds:
[e1, …, ek] = e1 : (e2 : ( … (ek : [])))
Furthermore:
y = [toUpper 'a', 'b', undefined]
λ> seq y ()
()
λ> :sprint y
y = "Ab*** Exception: Prelude.undefined
λ> :sprint y
*** Exception: Prelude.undefined
With lists of Char
s even actual evaluation is forced, but with other types things are still strange:
x = True : False : id False : []
y = [True, False, id False]
λ> seq x ()
()
λ> seq y ()
()
λ> :sprint x
x = True : _
λ> :sprint y
y = [True,False,_]
This seems to be just limited to sprint
. If you write a simple program like
import Control.Exception
x, y :: String
x = 'a' : 'b' : undefined : []
y = ['a', 'b', undefined]
main :: IO ()
main = do
evaluate x
evaluate y
putStrLn "Done"
then evaluating both to WHNF proceeds without touching undefined
.
My guess is that for some strange reason GHCi decides to print x
as a list, but y
as a string, which is the thing that forces the evaluation of the whole y
, not the seq
/evaluate
calls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With