在F#中执行委托多播等最简单的方法是什么?

时间:2013-07-17 19:14:46

标签: f#

目前我使用它并且工作正常:

let mutable notify = fun x -> x
let wrap f i = f(i); i

let a x = printf "%A" x
notify <- notify >> (wrap a)

notify "ss"

还有其他更好的方法吗?

为什么这不起作用?

let mutable notify = fun x -> x
let wrap f i = f(i); i

let a x = printf "%A" x  
let d x =
    (notify >> (wrap a)) x
notify <- d

notify "ss"

我不确定为什么第一个例子不会触发无限循环,但第二个例子不会。

似乎可变函数变量(点自由函数)具有与我预期不同的行为。关于这个主题我在哪里可以学到更多?

3 个答案:

答案 0 :(得分:3)

您不想使用MulticastDelegate吗?

type D<'T> = delegate of 'T -> 'T
let mutable notify = D<string>(fun x -> x)
let wrap f i = f(i); i
let a x = printfn "%A" x
notify <- Delegate.Combine(notify, D<string>(wrap a)) :?> _
notify.Invoke "ss"

您的第二个示例失败,因为d调用了notify,它无限地递归。

答案 1 :(得分:1)

我相信在函数式编程范例中组合多个处理程序的方法是让每个处理程序尾部调用它的第一个参数,传递其余的参数。然后用另一个处理程序调用它,形成一个链或单链接的处理程序列表。

答案 2 :(得分:1)

这是一个直截了当的选择。如果你想表示要调用的函数列表,那么为什么不保留一个(可变的)函数列表呢?

let handlers = ResizeArray()
let notify x = 
    for f in handlers do
        f x

handlers.Add(fun x -> printf "%A" x)

notify "ss"