f# - 我缺少什么: is function composition with multiple arguments possible?

标签 f# composition function-composition

我了解F#中函数组合的基础知识,例如here所述。

不过,也许我缺少了一些东西。 >><<运算符似乎是在假设每个函数仅接受一个参数的前提下定义的:

> (>>);;
val it : (('a -> 'b) -> ('b -> 'c) -> 'a -> 'c) = <fun:it@214-13>
> (<<);;
val it : (('a -> 'b) -> ('c -> 'a) -> 'c -> 'b) = <fun:it@215-14>

但是,我想做的事情如下:
let add a b = a + b
let double c = 2*c
let addAndDouble = add >> double   // bad!

但是,即使add的输出是double的输入所需的类型,也将被拒绝。

我知道我可以用一个元组参数重写add:
let add (a,b) = a + b

或者,我可以为第一个函数的所有可能参数编写一个新的运算符:
let inline (>>+) f g x y = g (f x y)
let doubleAdd = add >>+ double

但这似乎很愚蠢!我错过了更好的方法吗?

最佳答案

您想要的不是完全没有道理的,但是没有办法在F#的类型系统中指示广义组合运算符的类型。也就是说,没有统一的好方法

(>>) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c


(>>+) : ('a -> 'b -> 'c) -> ('c -> 'd) -> 'a -> 'b -> 'd

(更不用说无限多个高级Arity版本了)。因此,您别无选择,只能定义自己的其他运算符。实际上,我经常发现以“指向”样式let f x y = add x y |> double编写的代码比无点/“无指向” let f = add (>>+) double更具可读性。

关于f# - 我缺少什么: is function composition with multiple arguments possible?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5446199/

相关文章:

F# GPU 编程与用于处理数据的 KDB 相比,最快的是什么?

.net - 在签名文件中共享受歧视的联合

F#交互比编译快

haskell - 编写可选的 Aeson 解析器

c++ - 构造函数调用顺序与组合

Java 8 如何在没有 Lambda 的情况下编写函数?

f# - 带有分号分隔符和预定义架构的 CsvProvider

c++ - 预序列化消息对象 - 实现?

haskell - 函数组合运算符 (.) 和 fmap (<$>) 的区别

Haskell:如何编写函数 "backwards",例如 Clojure 的线程 (->)?