F# 使用相同的参数类型组合2个(或n个)(&x27;a->;单元)函数

F# 使用相同的参数类型组合2个(或n个)(&x27;a->;单元)函数,f#,action,composition,side-effects,function-composition,F#,Action,Composition,Side Effects,Function Composition,是否有某种形式的内置/术语我不知道,但它不同的“组成”两个'a->unit函数来生成一个;e、 g: let project event = event |> logDirections event |> stashDirections let dispatch (batch:EncodedEventBatch) = batch.chooseOfUnion () |> Seq.iter project 可能成为: let project = logDi

是否有某种形式的内置/术语我不知道,但它不同的“组成”两个
'a->unit
函数来生成一个;e、 g:

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
(如中所述)

(它需要将相同的参数传递给这两个参数,我正在寻求按顺序运行它们,没有任何异常处理欺骗问题等。)


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

你能对给定的数据应用函数数组吗? 例如,您可以定义:

let apply (arg:'a) (fs:(('a->unit) seq)) = fs |> Seq.iter (fun f -> f arg)
然后,您将能够执行以下操作:

apply 1 [(fun x -> printfn "%d" (x + 1)); (fun y -> printfn "%d" (y + 2))]

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

如果您想更深入地理解这个概念,那么可以说您正在将顺序组合操作从处理值提升到处理函数

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

let ($) a b = a; b
因此,
printfn“hi”$1
现在是一个副作用操作和某个表达式的顺序组合,其计算结果为
1
,其作用与
printfn“hi”相同;1

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

let lift op g h = (fun a -> op (g a) (h a))
您现在可以编写
lift(+)foo bar
,而不是编写例如
fun x->foo x+bar x
。因此,您有一种无点编写相同内容的方法—只需使用对函数有效的操作

现在,您可以使用
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
seq2
seq3
函数只包含两个操作,而
seqN
与Klark的
apply
函数的作用相同


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

+1谢谢-我希望你能像那样读懂我的心思。我喜欢这种语言(还有那个C:F:Jon Skeet:Tomas Petricek)。总的来说,我并不介意在F#中定义局部函数来实现类似的功能,但似乎应该有一些东西可以实现这一点。我想我会接受,尽管这并没有解决我对在函数式语言中构成副作用函数的渴望:D(说真的,我知道这是个坏主意,不是一件普通的事情)+1答案没有错,但我应该更明确地说,如何定义助手不是我的问题,这是我可以避免定义助手的原因。