2011-09-12 37 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