3

作为这里的一个附带问题,在 F# 中执行诸如委托多播之类的最简单方法是什么,我认为提出一个带有适当标题的完整问题可能会更好。

这个版本不会导致递归:(这里notify似乎是不可变的d

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

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

notify "ss"

这个版本会。(这里notify似乎是可变的d

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 // normal function
notify <- d

notify "ss" // endless loop

另一个失败版本:

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

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

notify "ss" // endless loop

我在哪里可以找到任何指南或更多资源来解释我们为什么会有这种行为差异。它是与特定的编译器/语言相关联,还是有适用于所有函数式语言的理论?

4

1 回答 1

3

不受控制的可变性是这种行为的原因。其他语言(如 Haskell)使用避免此类问题的软件事务内存技术提供受控可变性。此外,热切的评估在这里也起着重要的作用。

let d = (notify >> (wrap a)):在这种情况下,has 的任何值notify都将被组合起来(wrap a),结果将被分配给d

let d x = (notify >> (wrap a)) x: 在这里,函数的主体在你实际调用d函数之前不会执行,因此你得到的变异值notify

于 2013-07-19T12:35:59.877 回答