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

Haskell中的表达式计算:固定子表达式的类型会导致对父表达式进行不同程度的计算,haskell,lazy-evaluation,weak-head-normal-form,Haskell,Lazy Evaluation,Weak Head Normal Form,我无法解释以下行为: 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为其尺寸 我在阅读时意外发现了这种行

我无法解释以下行为:

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为其尺寸


我在阅读时意外发现了这种行为。

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

x :: Num a => a
所以

在GHC核心中,这个
y
是一个接受
Num
字典并给出一对的函数。如果要计算
y
,则GHCi将为您默认该值,并应用
整数
字典。但是从您所展示的情况来看,
sprint
似乎不会发生这种情况。因此你还没有一双鞋;您有一个生成一个的函数

当您专门处理
Int
时,字典将应用于
x
,因此您可以

x :: Int
y :: (Int, Int)
现在,
x
不再是字典中的函数,而是一个thunk。现在,不需要应用字典来计算
y
y
只是将pair构造函数应用于指向
x
thunk的两个指针。应用构造函数不算是计算,所以它从来不会延迟。

请参见,尽管我感到困惑的是,
y
的元组构造函数在这里是可见的,即使在单态情况下,所以它可能不是重复的。
x :: Int
y :: (Int, Int)