Haskell 中的表达式求值:固定子表达式的类型会导致对父表达式进行不同程度的求值

Expression Evaluation In Haskell: Fixing the type of a sub-expression causes parent expression to be evaluated to different degrees

我无法解释以下行为:

Prelude> let x = 1 + 2
Prelude> let y = (x,x)
Prelude> :sprint y
Prelude> y = _

现在,当我为 x 指定类型时:

Prelude> let x = 1 + 2 ::Int
Prelude> let y = (x,x)
Prelude> :sprint y
Prelude> y = (_,_)

为什么 x 的类型规范将 y 强制为其 weak head normal form (WHNF)

我在阅读 Simon Marlow's Parallel and Concurrent Programming In Haskell 时无意中发现了这种行为。

这是一个有根据的猜测。在你的第一个例子中,

x :: Num a => a

所以

y :: Num a => (a, a)

在 GHC 核心中,这个 y 是一个 函数 ,它接受一个 Num 字典并给出一对。如果您要 评估 y,那么 GHCi 将为您默认它并应用 Integer 字典。但是从您所展示的内容来看,sprint 似乎不会发生这种情况。因此你还没有一对;你有一个产生一个的函数。

当你专攻 Int 时,字典适用于 x,所以你得到

x :: Int
y :: (Int, Int)

x 不再是字典中的函数,而是一个 thunk。现在不需要应用字典来评估 yy 只是将 pair 构造函数应用于指向 x thunk 的两个指针。应用构造函数不算作计算,因此永远不会延迟延迟。