我缺少什么:可以使用多个参数进行函数组合吗?
我了解 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>
但是我想做什么,类似于以下内容:
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
但这看起来很愚蠢!有我错过的更好的方法吗?
I understand the basics of function composition in F#, as, for example, described here.
Maybe I am missing something, though. The >>
and <<
operators seem to have been defined with the assumption that each function only takes one argument:
> (>>);;
val it : (('a -> 'b) -> ('b -> 'c) -> 'a -> 'c) = <fun:it@214-13>
> (<<);;
val it : (('a -> 'b) -> ('c -> 'a) -> 'c -> 'b) = <fun:it@215-14>
What I'd like to do, however, is something like the following:
let add a b = a + b
let double c = 2*c
let addAndDouble = add >> double // bad!
But even though add
's output is of the type required for double
's input, that is rejected.
I know that I can rewrite add with one tuple argument:
let add (a,b) = a + b
Or I can write a new operator for every number of possible arguments to the first function:
let inline (>>+) f g x y = g (f x y)
let doubleAdd = add >>+ double
But it seems silly! Is there a better way that I've missed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您想要的并非完全不合理,但无法在 F# 的类型系统中指示广义组合运算符的类型。也就是说,没有好的方法来统一
和
(更不用说无限多个更高数量的版本)。因此,您别无选择,只能定义自己的附加运算符。在实践中,我经常发现以“尖头”风格编写的代码
let fxy = add xy |>无论如何,double 比无点/“无意义”let f = add (>>+) double 更具可读性。
What you want isn't totally unreasonable, but there would be no way to indicate the type of a generalized composition operator within F#'s type system. That is, there's no good way to unify
and
(not to mention the infinitely many higher arity versions). Therefore, you have no alternative but to define your own additional operators. In practice, I often find code written in the "pointed" style
let f x y = add x y |> double
more readable than the point-free/"pointless"let f = add (>>+) double
anyway.查看您上面发布的
>>
和<<
的类型。例如:它需要两个函数和一个值(
'a
)并返回另一个值。您需要带有两个函数和两个值的东西。因此,>>
和<<
都没有正确的类型签名。你的实现一点也不傻。只是您的需求在 F# 库中并不是现成的。感谢您拥有一种允许您定义自己的运算符的语言,如下所示:)
Look at the types of
>>
and<<
that you posted above. eg:It takes two functions and a value (
'a
) and returns another value. You need something that takes two functions and 2 values. Hence, both>>
and<<
don't have the correct type signature.Your implementation isn't silly at all. It's just that your requirement doesn't come out of the box in F#'s libraries. Be thankful that you have a language which allows you to define your own operators like this :)
将一堆参数线程化怎么样?
然后你可以编写任意数量的函数:
它可以工作:(
另请参阅具有多个输入参数的F#函数组合)
How about threading a stack of arguments through?
Then you can compose arbitrary arity functions:
And it works:
(see also F# Function Composition with multiple input parameters)