gpt4 book ai didi

f# - 组合 2 个(或 n)('a -> unit)具有相同 arg 类型的函数

转载 作者:行者123 更新时间:2023-12-01 09:25:29 24 4
gpt4 key购买 nike

是否有某种形式的内置/术语我不知道有点但它不同的“组合”两个 'a -> unit 函数来产生一个;例如:

let project event =
event |> logDirections
event |> stashDirections
let dispatch (batch:EncodedEventBatch) =
batch.chooseOfUnion () |> Seq.iter project

可能变成:

let project = logDirections FOLLOWEDBY stashDirections
let dispatch (batch:EncodedEventBatch) =
batch.chooseOfUnion () |> Seq.iter project

然后:

let dispatch (batch:EncodedEventBatch) =
batch.chooseOfUnion () |> Seq.iter (logDirections FOLLOWEDBY stashDirections)

我想人们可能会将它与 tee 进行比较(正如 FSFFAP's Railway Oriented Programming series 中提到的那样)。

(它需要将相同的 arg 传递给两者,我正在寻求按顺序运行它们而没有任何异常处理技巧问题等)

(我知道我可以做到 let project fs arg = fs |> Seq.iter (fun f -> f arg) 但我想知道是否有 内置的东西和/或我不知道的某种形式的组合库)

最佳答案

Klark 的 apply 函数是解决问题最直接的方法。

如果您想更深入地挖掘并更普遍地理解这个概念,那么您可以说您正在提升顺序组合操作,从处理 values 到处理 < em>函数。

首先,F# 中的 ; 构造可以看作是顺序组合运算符。可悲的是,您不能完全将其用作一个,例如(;) (因为它在第二个参数中是特殊且惰性的)但我们可以定义自己的运算符来探索这个想法:

let ($) a b = a; b

所以,printfn "hi"$ 1 现在是一个副作用操作和一些计算结果为 1 的表达式的顺序组合,它的作用与printfn "hi"; 1.

下一步是定义一个提升操作,将处理值的二元运算符转换为处理函数的二元运算符:

let lift op g h = (fun a -> op (g a) (h a))

而不是写例如fun x -> foo x + bar x,你现在可以写 lift (+) foo bar。因此,您可以通过一种无点的方式来编写相同的内容 - 只需使用适用于函数的操作。

现在您可以使用 lift 函数和顺序合成运算符来实现您想要的:

let seq2 a b = lift ($) a b
let seq3 a b c = lift ($) (lift ($) a b) c
let seqN l = Seq.reduce (lift ($)) l

seq2seq3 函数只组成两个操作,而 seqN 与 Klark 的 apply 做同样的事情功能。

应该说我写这个答案不是因为我认为以这种方式在F#中实现东西很有用,而是正如你提到的面向铁路的编程并要求背后更深层次的概念对此,看看如何用函数式语言组合是很有趣的。

关于f# - 组合 2 个(或 n)('a -> unit)具有相同 arg 类型的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25485774/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com