函数合并/组合在fsharp中

时间:2012-02-23 10:18:28

标签: f# functional-programming combinators

我有一个函数列表,它们接受与输入相同的类型,不同的类型作为输出

 [ f_i :  Mytype -> res:Sometype_i ] 

哪个操作可以将它们合并为以下类型的一个函数?

 f : Mytype -> \Product_i Mytype_i

相同,如果我有一个返回相同类型的函数列表

 [ f_i : Mytype_i -> res:Sometype ] 

哪个操作可以将它们合并为以下类型的一个函数?

 f : \Product_i Mytype_i ->  Mytype list

这将是一些规范的“preCombinator”或“postCombinator”。 (我想它在FP中有一个名字..)

2 个答案:

答案 0 :(得分:3)

你的第一个问题的答案是你不能这样做。列表是具有动态长度的数据结构,但生成的元组的长度必须在编译时静态知道。 (您可以使用反射构造生成的元组,并将其用作obj,但这并不是真的有用。)

在第二种情况下,您希望将函数列表转换为函数返回列表,这可以完成(两者都具有动态长度)。你可以这样写:

let funcs =
  [ (fun n -> n + 1)
    (fun n -> n * 2) ]

let merged =
  funcs |> List.fold (fun agg f ->
    fun inp -> (f inp)::(agg inp)) (fun _ -> [])

原始操作(传递给fold)是一个函数,它接受类型为TInp -> TOut list的函数和函数TInp -> TOut,并将它们组合成一个返回较长列表的函数。所以你也可以写:

// val addResult : ('a -> 'b list) -> ('a -> 'b) -> 'a -> 'b list  
let addResult agg f inp = (f inp)::(agg inp)

// val merge : ('a -> 'b) list -> ('a -> 'b list)
let merge funcs = funcs |> List.fold addResult (fun _ -> [])

答案 1 :(得分:3)

替代Tomas解决第二个问题的方法,还有以与最初相同的顺序返回功能的额外好处

let funcs =
  [ (fun n -> n + 1)
    (fun n -> n * 2) ]

let merged = fun input -> funcs |> List.map (fun f -> f input)