"Строгость" квадратных скобок
Я помещаю эти определения в файл:
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
.