F#Function具有多个输入参数的组合

时间:2010-07-10 05:54:33

标签: f#

我是F#的新手,我最近发现了函数组合运算符>>

我理解基本原则,以便这样的事情成为可能......

let Add1ToNum x = x +1
let Mul2ToNum y = y * 2
let FuncComp = Add1ToNum >> Mul2ToNum

但是,当你有几个具有不同数量的输入参数的函数时,如何处理合成...例如我希望能够执行以下操作...

let AddNums (x,y) = x+y
let MulNums (x,y) = x*y
let FuncComp = Add1 >> Mul2

这显然不起作用,因为AddNums返回一个int,而MulNums期待一个元组。

是否有某种形式的语法允许我完成此操作,或者如果我想使用函数组合,我是否必须始终执行某种中间函数来转换值?

对此的任何建议都将非常感激。

3 个答案:

答案 0 :(得分:8)

正如Yin和codekaizen指出的那样,你不能组合这两个函数来创建一个函数,将输入传递给第一个函数,然后将这个调用的输出传递给第二个函数(即,使用th {{1}运营商)。使用图表,你不能这样做:

>>

一个选项是更改功能并指定其中一个参数,以便可以组合功能。 codekaizen的例子使用了这个,也可以像这样编写(如果你使用currying而不是tupled参数):

     +---------+    +---------+
 --->| AddNums |--->| MulNums |--->
     +---------+    +---------+

组合函数的另一个选项是创建一个函数,它接受几个输入,将两个数字传递给第一个函数,然后用结果调用第二个函数,从原始输入调用另一个数字。使用图表:

let AddNums x y = x + y  
let MulNums x y = x * y  
let FuncComp = (AddNums 1) >> (MulNums 2)

如果你需要这样的东西,那么最好的选择是直接写,因为这可能不是一个经常重复的模式。直接地,这很容易(使用curried变体):

 -----------------\
 --->+---------+   \+---------+
 --->| AddNums |--->| MulNums |--->
     +---------+    +---------+

如果你想更一般地写一些这样的东西(或仅仅是为了好奇心),你可以写这样的东西(这次使用函数的三元组版本)。 let AddNums x y = x + y let MulNums x y = x * y let FuncComp x y z = AddNums z y |> (MulNums z) 运算符的灵感来自Arrows

&&&

答案 1 :(得分:1)

正如Yin指出的那样,你的作品在作曲时并不匹配。 AddNumsMulNums的类型为int * int -> int,因此您不能指望将其中一个的输出插入另一个的输入中。

我注意到你的最后一行是let FuncComp = Add1 >> Mul2这可能是一个拼写错误,但是会让你深入了解如何“绑定”带有元组的函数以便它们组成:

let Add1 x = AddNums(x, 1)
let Mul2 x = MulNums(x, 2)
let FuncComp = Add1 >> Mul2 

运行时:

  

FuncComp(1);;

     

val it:int = 4

答案 2 :(得分:1)

另一种选择是使stack->堆栈函数与RPN计算器非常相似。例如:

let bin f = function a :: b :: t -> f b a :: t
let add = bin (+)
let mul = bin (*)

也许是将文字推送到堆栈的函数:

let lit n t = n :: t

然后是纯粹的构图:

> (lit 9 >> lit 12 >> add >> lit 2 >> mul) []
42

您甚至可以添加堆栈重排功能:

let drop = function _ :: t -> t
let dup  = function x :: t -> x :: x :: t
let swap = function x :: y :: t -> y :: x :: t

做一些事情:

let square = dup >> mul
let cube = dup >> dup >> mul >> mul
let negate = lit -1 >> mul

只是疯狂的实验!

(另见http://blogs.msdn.com/b/ashleyf/archive/2011/04/21/programming-is-pointless.aspx