我有一个函数列表,它们接受与输入相同的类型,不同的类型作为输出
[ 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中有一个名字..)
答案 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)