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

具有多个输入参数的F#函数组合,f#,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 >

我是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需要一个元组

是否有某种形式的语法允许我实现这一点,或者如果我想使用函数组合,我是否必须始终执行某种中介函数来转换值


任何对此提出建议的人都将不胜感激。

正如尹指出的,你的类型在写作时不匹配
AddNums
MulNums
属于
int*int->int
类型,因此不能期望将一个的输出插入另一个的输入

我注意到,您的最后一行是
let funcomp=Add1>>Mul2
,这可能是一个输入错误,但提供了有关如何“绑定”接受元组的函数的见解,以便它们组成:

let Add1 x = AddNums(x, 1)
let Mul2 x = MulNums(x, 2)
let FuncComp = Add1 >> Mul2 
运行时:

funcomp(1)

val it:int=4


正如尹和codekaizen所指出的,您不能组合这两个函数来创建一个将输入传递给第一个函数,然后将此调用的输出传递给第二个函数的函数(即,使用th
>
操作符)。使用图表,您无法执行以下操作:

     +---------+    +---------+
 --->| AddNums |--->| MulNums |--->
     +---------+    +---------+
一个选项是更改函数并指定其中一个参数,以便可以组合函数。codekaizen的示例使用了这一点,也可以这样编写(如果使用curry而不是tuple参数):

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

 -----------------\
 --->+---------+   \+---------+
 --->| AddNums |--->| MulNums |--->
     +---------+    +---------+
如果您需要这样的内容,那么最好的选择是直接编写,因为这可能不会是一个经常重复的模式。直接来说,这很简单(使用curried变体):

如果您想更一般地编写类似的内容(或者只是出于好奇),您可以编写类似的内容(这次使用的是元组版本的函数)。
&&&
操作符的灵感来自:


另一个选择是使stack->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
只是一个疯狂的实验


(另请参见)

我不太明白您使用
AddNum>>MulNums
的意义,AddNums的输出是一个数字,因此不是MulNums的有效输入格式,这意味着这两个函数根本不组合。感谢codekaizen,在我的问题中我确实指出,我知道一个函数的输出与另一个函数的输入不同,函数复合运算符不起作用,但我正在寻找一个可能的替代解释。谢谢Thomas,这很好地解释了这一点@汤姆斯:恐怕你用错了箭头中的运算符。应为(***);)let(***)fg(a,b)=(fa,gb)let(&&&)fga=(fa,ga)
> (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