2011-09-12 56 views
3

我很好奇,爲什麼這Tupled函數組合

let f = (fun a b -> a, b) >> obj.Equals 

給出了錯誤

命名沒有訪問成員或對象的構造函數 '等於' 需要1個參數

但這種作品

let f = (fun a -> a, a) >> obj.Equals 
+1

該錯誤消息我得到的,當我嘗試這是_this表達式預計有'a - >'b *'a'類型,但是這裏有類型'c *'d'_,這有點更多信息。它更清楚地對應於kvb在他的好答案中寫的。我不知道你爲什麼會得到不同的信息... –

回答

3

考慮類型。 (>>)的類型爲('a -> 'b) ->('b -> 'c) -> ('a -> 'c),但您試圖使用類型爲'a -> ('b -> 'a*'b)obj * obj -> bool的參數對其進行調用,因此無法將它們組合在一起。

你當然可以定義一個新的組合子用於組成的二進制和一元函數:

在這種情況下
let (>>*) f g a b = f a b |> g 

,你可以在你的榜樣,而不是(>>)使用它。

+0

啊。我忽略了'''第一個arg是一元的。那個奇怪的錯誤信息(我仍然得到)正在拋棄我。謝謝。 – Daniel

6

沒有定義一個新的組合子操作:

let f = (fun a b -> a, b) >> (<<) obj.Equals 

>> (<<)是一個很好的技巧,也可以擴展爲多個參數:

let compose3 f g = f >> (<<) ((<<) g) 
val compose3 : ('a -> 'b -> 'c -> 'd) -> ('d -> 'e) -> ('a -> 'b -> 'c -> 'e) 
+0

+1這是一個巧妙的把戲! – Daniel