有人可以解释Haskell在运算符($)
和($!)
(美元符号与美元符号感叹号)之间的区别吗?
到目前为止,我还没有看到$!
在任何地方的使用,但在浏览Haskell reference时,我注意到它的存在,并且它与$
具有完全相同的定义。在Haskell解释器(GHCi)中尝试一些简单语句时,我找不到任何差异,在搜索haskell tutorial
时,我也无法在列出的顶级教程中找到对运算符的任何引用。
所以,出于好奇,有什么区别,如果有的话?
答案 0 :(得分:43)
($!)
是严格的功能应用程序。也就是说,它在评估函数之前评估参数。
这与Haskell中的正常惰性函数应用相反,例如f x
或f $ x
,它首先开始评估函数f
,并且仅在需要时计算参数x
。
例如,succ (1 + 2)
会通过创建thunk来延迟添加1 + 2
,并首先开始评估succ
。只有在需要succ的参数时才会对1 + 2
进行评估。
但是,如果您确定始终需要函数的参数,则可以使用($!)
,它将首先将参数计算为弱头法线形式,然后输入函数。这样,你就不会创建一大堆thunks,这样可以更有效率。在此示例中,succ $! 1 + 2
首先计算3
,然后输入函数succ
。
请注意,使用严格的函数应用程序替换普通函数应用程序并不总是安全的。例如:
ghci> const 1 (error "noo!")
1
ghci> const 1 $! (error "noo!")
*** Exception: noo!
答案 1 :(得分:7)