Haskell seq到达构造函数后立即停止
说明seq一到达构造函数就停止Haskell seq到达构造函数后立即停止,haskell,Haskell,说明seq一到达构造函数就停止 case1 = 1:repeat undefined `seq` "OK" case2 = (undefined,undefined) `seq` "OK" 我们有 1:repeat undefined = (:) 1 (repeat undefined) (undefined,undefined) = (,) undefined undefined 我理解为什么case1函数返回“OK”。 但是为什么case2函数也返回“OK”? 我认为案例2将返回“Pre
case1 = 1:repeat undefined `seq` "OK"
case2 = (undefined,undefined) `seq` "OK"
我们有
1:repeat undefined = (:) 1 (repeat undefined)
(undefined,undefined) = (,) undefined undefined
我理解为什么case1函数返回“OK”。
但是为什么case2函数也返回“OK”?
我认为案例2将返回“Preluded.undefined”,因为在第一个案例中,1被计算,所以我认为在第二个案例中,undefined也应该被计算
但是为什么case2函数也返回“OK”
因为两个未定义的都在(,)
构造函数中,因此不进行计算
我认为案例2将返回“Preluded.undefined”,因为在第一个案例中,对1进行了评估
1
在第一种情况下不进行求值-正如书中所说,求值以(:)
(第一个构造函数)停止<代码>未定义:未定义的'seq`“OK”
仍然计算为“OK”。RWH说
考虑值(1+2):(3+4):[]
。如果我们对此应用seq
,它将评估(1+2)
thunk
这是不正确的,Phil Thomas在在线版本中的评论指出:
在ghci中,如果输入以下内容:
let x = (1+2):(3+4):[]
seq x True
:print x
你会看到:
x = [(_t1::Integer),(_t2::Integer)]
尚未评估(1+2)
。cons是一个中缀运算符,似乎位于(1+2)
之后,但它实际上是seq遇到的第一件事
我们可以将seq
定义为:
⊥ `seq` b = ⊥
a `seq` b = b
为了确定某个值是否为底部,必须仅对其最外层的构造函数求值。1:repeat undefined
的最外层构造函数不是1
,而是(:)
。例如,您可以将1:[]
可视化为:
(:)
/ \
1 []
此表示中最外层的构造函数是最顶层的构造函数
case1 = 1:repeat undefined `seq` "OK"
case2 = (undefined,undefined) `seq` "OK"
这意味着1:repeat undefined
将被计算为\uu:
,而不是1:\u
(其中\u
表示未计算的thunk)
类似地,(未定义,未定义)
的最外层构造函数是(,)
,它将被求值为(,,)
,而不是(未定义,未定义)
或未定义的RHW表示“考虑值(1+2):(3+4):[]。如果我们将seq应用于此,它将求值为(1+2)thunk–所以我认为1应该被计算。1+2
与你的问题中的(,)12
或(,)未定义的未定义的未定义的
不一样。一个是计算,另一个是数据构造。@neo2500这在书中似乎是一个错误。未定义的:(3+4):[]`seq`“OK”
计算为“OK”“-肯定不会计算:
的左操作数。@ThomasM.DuBuisson但(1+2):…
与(1+2…)
相同(就表达式相对于构造函数的位置而言)。书中的这一行似乎是错的(或者neo和我都误读了)。@neo2500这本书并不清楚“将seq
应用于此”是什么意思seq(1+2)“OK”
会将1+2
求值为3
,但您可以在GHCi中检查(1+2):(3+4):[]
seq“OK”`不会求值列表中的任何元素:>让x=(1+2):(3+4):[];>顺序x“确定”;>:sprint x-->x=\uu