1

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

 [ 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 中有一个名字..)

4

2 回答 2

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 _ -> [])
于 2012-02-23T10:31:45.017 回答
3

Tomas 对第二个问题的解决方案的替代方案,其额外的好处是以与最初相同的顺序返回函数

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

let merged = fun input -> funcs |> List.map (fun f -> f input)
于 2012-02-23T10:48:34.373 回答