2012-01-13 92 views

回答

7

那麼,f1 . f2 xf1f2 x的組成。你的意思可能是(f1 . f2) x,或者相當於f1 . f2 $ x;即f1f2的組成,應用於x

答案可以通過查看類型中找到:

($) :: (a -> b) -> a -> b 
(.) :: (b -> c) -> (a -> b) -> a -> c 

簡單,($)適用的功能,它的參數,和(.) 它的兩個參數。兩條鏈

f . g . h $ x 

f $ g $ h $ x 

是等價;前者通常是首選,因爲使用剪切和粘貼將構圖重構爲自己的功能更容易,但這不是普遍的偏好。視覺噪音也稍低。

實際上,($)id等同於身份函數;它只是返回給定的函數。它只是有用的,因爲它的運算符優先級很低(實際上是最低的)。

+1

我會說''($)'對於像'map($ 3)[(+5),(* 2),(subtract 4)]' – 2012-01-13 23:52:03

+0

這樣的東西也是有用的(或者至少很酷)我以前從來沒有想過,但你也可以做'map(\'id \'3)[(+5),(* 2),(subtract 4)]'! :) – Rotsor 2012-01-14 17:04:30

6

($)(.)都沒有做任何特殊的「綁定表達」。他們只是其他運營商。所有你需要知道的是他們被定義爲什麼,他們的固定是什麼。對於第一個:

infixr 0 $ 

f $ x = f x 

所以它是功能應用程序,具有非常低的優先級和右關聯性。所以如果你有f x $ g y z這意味着(f x) (g y z)這相當於f x (g y z)。它主要用於避免括號。

對於第二個:

infixr 9 . 

(.) f g x = f (g x) 

這看起來起初相似,但(.)是在兩個功能,而不是一個功能和參數操作,並具有很高的優先級。所以如果你有(f x . g y) z這意味着(f x) ((g y) z)這相當於f x (g y z)

的關鍵區別在於(.)你可以鏈衆多功能一起,像f1 . f2 . f3,而與($)你只能申請更多的功能的結果。因此,在像f x $ g y $ h z這樣的表達式中,如果您決定用一整個值列表替換單個值z,則不能只寫map (f x $ g y $ h) zs,因爲函數在括號化表達式中沒有任何用處。如果您改爲寫f x . g y . h $ z之類的東西,您可以刪除最終的功能應用程序並獲得map (f x . g y . h) zs,它將起作用。