繁体   English   中英

Haskell 中的求值是如何工作的,对于有约束的表达式

[英]How does evaluation in Haskell work, for expressions with constraints

假设我用 GHCi 写:

GHCi> let x = 1 + 2 :: Integer
GHCi> seq x ()
GHCi> :sprint x

GHCi 按照自然预期打印x = 3

然而,

GHCi> let x = 1 + 2
GHCi> seq x ()
GHCi> :sprint x

产量x = _

两个表达式之间的唯一区别是它们的类型( IntegerNum a => a )。 我的问题是究竟发生了什么,为什么在后一个例子中似乎没有评估x

主要问题是

let x = 1 + 2

定义一个forall a. Num a => a类型的多态forall a. Num a => a forall a. Num a => a ,这是一个类似于函数的评估结果。

x每次使用都可以使用不同的类型,例如x :: Intx :: Integerx :: Double等等。 这些结果不会以任何方式“缓存”,而是每次都重新计算,就像x是一个被多次调用的函数,可以这么说。

实际上,类型类的常见实现将这样的多态x为函数

x :: NumDict a -> a

其中NumDict a论点的上方由编译器自动添加的,而携带的信息a是一个Num类型,包括如何执行另外,如何解释整数内部文字a上,等等。 这称为“字典传递”实现。

因此,多次使用多态x确实对应于多次调用函数,从而导致重新计算。 为了避免这种情况,Haskell 中引入了(可怕的)单态限制,强制x改为单态。 MR 不是一个完美的解决方案,在某些情况下会产生一些令人惊讶的类型错误。

为了缓解这个问题,在 GHCi 中默认禁用 MR,因为在 GHCi 中我们不太关心性能——可用性在那里更为重要。 然而,正如您发现的那样,这会导致重新计算重新出现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM