代码之家  ›  专栏  ›  技术社区  ›  Mark Pearl

多输入参数F#函数合成

f#
  •  6
  • Mark Pearl  · 技术社区  · 16 年前

    我对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需要一个tuple。

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

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

    3 回复  |  直到 16 年前
        1
  •  8
  •   Tomas Petricek    16 年前

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

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

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

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

     -----------------\
     --->+---------+   \+---------+
     --->| 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

    let AddNums (x,y) = x + y 
    let MulNums (x,y) = x * y  
    
    let (&&&) f g (a, b) = (f a, g b)
    let FuncComp = (AddNums &&& id) >> MulNums
    
    // First two numbers are added, result is multiplied by the third one
    FuncComp ((9, 12), 2) // Gives '42'
    
        2
  •  2
  •   AshleyF    15 年前

    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 )

        3
  •  1
  •   Community Mohan Dere    6 年前

    AddNums MulNums int * int -> int

    我注意到你的最后一句话是 let FuncComp = Add1 >> Mul2

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

    运行时:

    funcomp(1);;

    值:int=4