方括号的“严格性”

时间:2015-10-16 18:52:57

标签: haskell ghc ghci

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

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呢?

我看到的内容似乎与报告的section 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 个答案:

答案 0 :(得分: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"

然后evaluating WHNF enter image description here继续进行undefined

我的猜测是因为一些奇怪的原因GHCi决定打印x作为列表,但y作为字符串,这是强制评估整个y的事情而不是seq / evaluate来电。