2010-05-07 211 views
26

任何人都可以解释(与美元符号感叹号美元符号)的运营商($)($!)之间哈斯克尔区别?

我到目前为止在任何地方都没有看到过使用$!,但在浏览Haskell reference时,我注意到它的存在,并且它具有与$完全相同的定义。在Haskell解释器(GHCi)中尝试一些简单的语句时,我找不到任何区别,在搜索haskell tutorial时,我也无法在顶部列出的教程中找到对操作员的任何引用。

所以,只是出于好奇,有什么区别,如果在所有?

+1

HIYF:http://www.haskell.org/hoogle/?q=%28%24!%29&format=sherlock – jberryman 2010-05-07 21:19:25

+0

另请参阅http://stackoverflow.com/questions/940382/haskell-difference-between-点和美元符号 – 2011-04-19 01:44:50

回答

42

($!)是严格的功能应用。也就是说,它在评估函数之前评估参数。

这与在Haskell,例如正常懒惰函数应用f xf $ x,它首先开始评估函数f,并且只在需要时计算参数x

例如succ (1 + 2)将通过创建thunk来延迟添加1 + 2,并开始首先评估succ。只有当需要succ的参数时,才会评估1 + 2

但是,如果您确定始终需要函数的参数,则可以使用($!),它将首先评估参数为弱头标准形式,然后输入该函数。这样,你不会创建一大堆thunk,这可以更有效率。在此示例中,succ $! 1 + 2将首先计算3,然后输入函数succ

注意,它并不总是安全的,只需更换严格的功能应用的正常功能应用。例如:

ghci> const 1 (error "noo!") 
1 
ghci> const 1 $! (error "noo!") 
*** Exception: noo! 
+4

最后一个例子更多关于'error'的副作用。功能语义永远不应该受到刘海的伤害(“par”和“seq”相同)。放置刘海有时可能会增加速度/记忆力,有时会减少。在某些特殊情况下,它可能会导致永无止境的计算'const 1 $! (最后[1 ..])'。 – ony 2010-05-09 12:47:11

+8

那么,信息的印刷是一个副作用,但重点是'错误'是⊥(底部)。就像一个永无止境的计算是⊥。如果你使用'seq'来评估⊥,你的程序的语义会改变。这就是为什么你应该小心诸如'seq'和'($!)',它可以增加(或减少)你程序的效率,但它也可能使它崩溃在通常不应该有的地方。 – 2010-05-09 19:19:16

7

请参阅seq函数,该函数强制评估值。 $!是根据seq定义的。

This是一个博客帖子足见其使用的一些细微差别。

+0

啊,愚蠢的我!它在zvon上也是如此描述'$!',但由于某种原因,等号不会响起... 感谢您的博客链接。 – 2010-05-07 10:07:37

+1

'f $! x = x''seq'' f x' http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Prelude。html#%24%21 – 2011-08-03 21:02:54

+0

尽管这个链接可能回答这个问题,但最好在这里包含答案的基本部分,并提供供参考的链接。如果链接页面更改,则仅链接答案可能会失效。 - [来自评论](/ review/low-quality-posts/17886026) – guradio 2017-11-09 07:29:16

相关问题