Kev*_*ntu 10 f# composition function-composition
我理解F#中函数组合的基础知识,例如,这里描述的.
也许我错过了一些东西.在>>与<<运营商似乎已经与各功能只需要一个参数的假设定义:
> (>>);;
val it : (('a -> 'b) -> ('b -> 'c) -> 'a -> 'c) = <fun:it@214-13>
> (<<);;
val it : (('a -> 'b) -> ('c -> 'a) -> 'c -> 'b) = <fun:it@215-14>
Run Code Online (Sandbox Code Playgroud)
但是,我想做的事情如下:
let add a b = a + b
let double c = 2*c
let addAndDouble = add >> double // bad!
Run Code Online (Sandbox Code Playgroud)
但即使add输出是输入所需的类型double,也会被拒绝.
我知道我可以用一个元组参数重写add:
let add (a,b) = a + b
Run Code Online (Sandbox Code Playgroud)
或者我可以为第一个函数的每个可能的参数编写一个新的运算符:
let inline (>>+) f g x y = g (f x y)
let doubleAdd = add >>+ double
Run Code Online (Sandbox Code Playgroud)
但它似乎很傻!有没有更好的方法,我错过了?
kvb*_*kvb 12
你想要的并不是完全不合理的,但是没有办法在F#的类型系统中指出广义合成运算符的类型.也就是说,没有好的方法来统一
(>>) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c
Run Code Online (Sandbox Code Playgroud)
和
(>>+) : ('a -> 'b -> 'c) -> ('c -> 'd) -> 'a -> 'b -> 'd
Run Code Online (Sandbox Code Playgroud)
(更不用说无数更高级的arity版本).因此,除了定义自己的附加运算符之外别无选择.在实践中,我经常发现以"尖头"风格编写的代码let f x y = add x y |> double比无点/"无意义"更具可读性let f = add (>>+) double.