方括号的"严格性"

kir*_*gin 15 haskell ghc ghci

我把这些定义放在一个文件中:

x = 'a' : 'b' : 'c' : []
y = ['a', 'b', 'c']
Run Code Online (Sandbox Code Playgroud)

(重要的是在文件中定义那些,而不是在GHCi中,因为在后一种情况下,事情变得更加奇怪,但这是另一个问题.)

现在,我在GHCi中加载此文件并:

?> :sprint x
x = _
?> :sprint y
y = _
?> seq x ()
()
?> seq y ()
()
?> :sprint x
x = 'a' : _
?> :sprint y
y = "abc"
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?我理解在这种情况下会发生什么x,这正是我的预期.但那怎么样y

我所看到的似乎与报告的第3.7节相矛盾,后者说:

翻译:以下标识成立:

[e1, …, ek] = e1 : (e2 : ( … (ek : [])))
Run Code Online (Sandbox Code Playgroud)

此外:

y = [toUpper 'a', 'b', undefined]
Run Code Online (Sandbox Code Playgroud)
?> seq y ()
()
?> :sprint y
y = "Ab*** Exception: Prelude.undefined
?> :sprint y
*** Exception: Prelude.undefined
Run Code Online (Sandbox Code Playgroud)

随着Chars的列表甚至强制实际评估,但与其他类型的东西仍然是奇怪的:

x = True : False : id False : []
y = [True, False, id False]
Run Code Online (Sandbox Code Playgroud)
?> seq x ()
()
?> seq y ()
()
?> :sprint x
x = True : _
?> :sprint y
y = [True,False,_]
Run Code Online (Sandbox Code Playgroud)

Pet*_*lák 3

这似乎仅限于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"
Run Code Online (Sandbox Code Playgroud)

然后将两者评估WHNF而不触及undefined

我的猜测是,出于某种奇怪的原因,GHCi 决定打印x为列表,而是y打印为字符串,这是强制评估整体y而不是seq/evaluate调用的原因。