表达式评估在Haskell中:修复子表达式的类型会导致父表达式被评估到不同程度

uns*_*hul 8 haskell lazy-evaluation weak-head-normal-form

我无法解释以下行为:

Prelude> let x = 1 + 2
Prelude> let y = (x,x)
Prelude> :sprint y
Prelude> y = _
Run Code Online (Sandbox Code Playgroud)

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

Prelude> let x = 1 + 2 ::Int
Prelude> let y = (x,x)
Prelude> :sprint y
Prelude> y = (_,_)
Run Code Online (Sandbox Code Playgroud)

为什么x的类型规范强制y为其弱头正规形式(WHNF)

我在阅读Simon Marlow在Haskell中的并行和并发编程时偶然发现了这种行为.

dfe*_*uer 10

这是一个明智的猜测.在你的第一个例子中,

x :: Num a => a
Run Code Online (Sandbox Code Playgroud)

所以

y :: Num a => (a, a)
Run Code Online (Sandbox Code Playgroud)

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

当你专注于Int,字典被应用到x,所以你得到

x :: Int
y :: (Int, Int)
Run Code Online (Sandbox Code Playgroud)

而不是字典中的函数,x现在是一个thunk.现在不需要应用字典来评估y!y只是对构造函数的应用程序指向xthunk的两个指针.应用构造函数不算作计算,所以它永远不会延迟延迟.