简单示例以澄清记忆和严格性

时间:2018-10-20 14:48:52

标签: haskell

1。

ghci> let x = trace "one" 1 in (x, x)

(one
1,one
1)

我希望let-expr能记住x,所以结果如下:

(one
1,1)

2。

ghci> let !x = undefined in 1

...
error
...

好的,严格评估bang-pattern

ghci> let !x = trace "one" 1 in 1

    1

由于严格,我希望结果看起来像这样:

one
1

1 个答案:

答案 0 :(得分:4)

您一直为以下事实所困扰:从GHC 7.8.1开始,默认情况下GHCi中的monomorphism restriction被禁用。这意味着x绑定被普遍化为具有类型的,受类型限制的多态绑定

x :: Num a => a

因为1是多态数文字。即使此类型不包含任何功能箭头(->),在运行时它的行为也更像一个函数,而不是一个值,因为它实际上是一个接受Num类型类字典并使用的函数它来构造结果。

您可以通过显式注释文字以避免多态性来避免这种情况:

ghci> let x = trace "one" (1 :: Integer) in (x, x)
(one
1,1)
ghci> let !x = trace "one" (1 :: Integer) in 1
one
1

通常,上述单态性限制是适当的,恰好是为了防止这种混淆,在这种混淆中,语法上是值定义的绑定可以对其RHS进行多次评估。链接的答案描述了限制的一些折衷,但是,如果需要,您可以将其重新打开,这将使您的原始示例达到您的期望:

ghci> :set -XMonomorphismRestriction
ghci> let x = trace "one" 1 in (x, x)
(one
1,1)
ghci> let !x = trace "one" 1 in 1
one
1