Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

“Strictness” of square brackets

Tags:

haskell

ghc

ghci

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 Chars 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,_]
like image 844
kirelagin Avatar asked Oct 16 '15 18:10

kirelagin


1 Answers

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.

like image 164
Petr Avatar answered Oct 14 '22 10:10

Petr