2013-07-19 19 views
3

作为一个侧面的问题在这里What's the easiest way to do something like delegate multicast in 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" 

这个版本会。 (这里notifyd似乎可变)

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 

我在哪里可以找到任何指导或更多资源到我们为什么有这样的行为差异。它是否与特定的编译器/语言绑定,或者是否存在适用于所有功能语言的理论?

回答

3

不受控制的可变性是导致此行为的原因。像Haskell这样的其他语言使用软件事务内存技术来提供可控的可变性,从而避免了这些问题。另外,急切的评价在这里扮演着重要的角色。

let d = (notify >> (wrap a)):在这种情况下,任何的notify值将与(wrap a)组成,结果将被分配到d

let d x = (notify >> (wrap a)) x:在这里,不执行功能的身体,直到你真正调用d功能因此你得到的变异值为notify