f# - 点自由函数不会导致递归,但正常函数会在这里吗?

标签 f# functional-programming lazy-evaluation pointfree

这里作为附带问题What's the easiest way to do something like delegate multicast in F#我认为最好提出一个带有适当标题的完整问题。

这个版本不会导致递归:(这里的 notifyd 中似乎是不可变的)

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

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

最佳答案

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

let d = (notify >> (wrap a)) :在这种情况下,notify 的任何值都将由 (wrap a)< 组成 并将结果分配给 d

令 d x = (notify >> (wrap a)) x :这里,函数体直到你实际调用 d 函数才会执行,因此你得到了 的变异值通知

关于f# - 点自由函数不会导致递归,但正常函数会在这里吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17745892/

相关文章:

scala - 我可以检查 Scala 中是否已计算惰性 val 吗?

R 惰性评估- 不工作

F# 为二叉搜索树制作 ToString 方法

c# - 递归函数、堆栈溢出和 Y 组合器

scala - 功能流水线scala

math - 函数式编程和马尔可夫链有某种关系吗?

scala - 组合序列的惯用 Scala 解决方案

Java 惰性求值语义

Linq 类似函数 GroupMultipleValBy

f# - 如何在FSharp中以XML序列化数组的数组