"Строгость" квадратных скобок

Я помещаю эти определения в файл:

x = 'a' : 'b' : 'c' : []
y = ['a', 'b', 'c']

(Важно определить файлы в файле, а не в GHCi, потому что в последнем случае все становится еще более странным, но это еще один вопрос.)

Теперь я загружаю этот файл в GHCi и:

λ> :sprint x
x = _
λ> :sprint y
y = _
λ> seq x ()
()
λ> seq y ()
()
λ> :sprint x
x = 'a' : _
λ> :sprint y
y = "abc"

Что здесь происходит? Я понимаю, что происходит в случае x, именно это я и ожидал. Но как насчет y?

То, что я вижу, кажется, противоречит разделу 3.7 Отчета, в котором говорится:

Перевод: Имеет место следующее:

[e1, …, ek] = e1 : (e2 : ( … (ek : [])))

Далее

y = [toUpper 'a', 'b', undefined]
λ> seq y ()
()
λ> :sprint y
y = "Ab*** Exception: Prelude.undefined
λ> :sprint y
*** Exception: Prelude.undefined

С списками Char даже фактическая оценка принудительно, но с другими типами все еще странно:

x = True : False : id False : []
y = [True, False, id False]
λ> seq x ()
()
λ> seq y ()
()
λ> :sprint x
x = True : _
λ> :sprint y
y = [True,False,_]

Ответы

Ответ 1

Похоже, что это ограничивается sprint. Если вы пишете простую программу типа

import Control.Exception

x, y :: String
x = 'a' : 'b' : undefined : []
y = ['a', 'b', undefined]

main :: IO ()
main = do
    evaluate x
    evaluate y
    putStrLn "Done"

затем оценивая как WHNF продолжается, не касаясь undefined.

Я предполагаю, что по какой-то странной причине GHCi решает распечатать x в качестве списка, но y как строку, что и заставляет оценивать целое y, а не seq/evaluate.