2010-05-07 214 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

相關問題