我读过$!运算符会强制执行严格的计算。那为什么这个还是有效的?
Prelude> take 10 $! repeat 1
[1,1,1,1,1,1,1,1,1,1]
我原本以为ghc会永远试图计算由1组成的无限列表。
我读过$!运算符会强制执行严格的计算。那为什么这个还是有效的?
Prelude> take 10 $! repeat 1
[1,1,1,1,1,1,1,1,1,1]
我原本以为ghc会永远试图计算由1组成的无限列表。
$!
强制其第二个参数进入弱头归约范式,这基本上意味着它评估其参数的最外层构造函数。因此在您的情况下,它不会强制评估整个列表,而只会评估最外层(即第一个):
构造函数。
有一个很好的关于正常形式与WHNF的解释,请参阅Haskell:什么是弱头归约范式?。
请注意,如果您强制评估整个列表(例如使用来自Control.DeepSeq
模块的$!!
运算符),则程序将无法终止:
λ: import Control.DeepSeq (($!!))
λ: take 10 $!! repeat 1
^C
n > 0
,take n
必须强制列表进入 WHNF,因此take 10 $! repeat 1
在操作上与take 10 $ repeat 1
相同。 - Luis Casillas