fsharp 中的函数合并/组合器

发布于 2025-01-07 23:33:46 字数 465 浏览 0 评论 0原文

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

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

I have a list of functions accepting the same type as an input, different types as output

 [ f_i :  Mytype -> res:Sometype_i ] 

Which operation can merge them into one function of the following type ?

 f : Mytype -> \Product_i Mytype_i

Identically, if I have a list of functions returning the same type

 [ f_i : Mytype_i -> res:Sometype ] 

Which operation can merge them into one function of the following type ?

 f : \Product_i Mytype_i ->  Mytype list

It would be some canonical "preCombinator" or "postCombinator".
(I imagine it has a name in FP..)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

草莓味的萝莉 2025-01-14 23:33:46

第一个问题的答案是,一般来说你不能这样做。列表是具有动态长度的数据结构,但结果元组的长度必须在编译时静态已知。 (您可以使用反射构造结果元组并将其用作 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 -> TInp 类型的函数。 TOut 列表 和函数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 _ -> [])

The answer to your first question is that you cannot do that in general. A list is a data structure with dynamic length, but the length of the resulting tuple has to be known statically at compile time. (You could construct the resulting tuple using reflection and use it as obj, but that's not really useful.)

In the second case, you want to turn a list of functions into a function returning list, which can be done (both have dynamic length). You can write something like:

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 _ -> [])

The primitive operation (passed to fold) is a function that takes a function of type TInp -> TOut list and a function TInp -> TOut and combines them into a function returning a longer list. So you could also write:

// 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 _ -> [])
肤浅与狂妄 2025-01-14 23:33:46

针对第二个问题的托马斯解决方案的替代方案,其额外好处是按照与最初相同的顺序返回函数

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

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

An alternative to Tomas' solution for the second problem with the added bonus of returning the functions in the same order as they were initially

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

let merged = fun input -> funcs |> List.map (fun f -> f input)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文