我需要帮助来理解我当前的 OOP 状态概念与 Haskell 或 Clojure 等函数式语言中的实现方式之间的差异。

使用一个陈词滥调的例子,假设我们正在处理简化的银行帐户对象/结构/任何东西。在 OOP 语言中,我有一些类保存对 BankAccount 的引用,其中包含利率等实例变量,以及 setInterestRate() 等方法,这些方法会更改对象的状态并且通常不返回任何内容。在 Clojure 中,我有一个银行帐户结构(一个美化的哈希图),以及接受银行帐户参数和其他信息并返回一个新结构的特殊函数。因此,我现在没有更改原始对象的状态,而是返回了一个带有所需修改的新对象。

所以...我该怎么办?覆盖引用旧银行帐户的任何变量?如果是这样,这比状态改变的 OOP 方法有优势吗?最后,在这两种情况下,似乎都有一个变量引用具有必要更改的对象。尽管我是个弱智,但我对发生的事情只有一个模糊的概念。

我希望这是有道理的,感谢您的帮助!

有帮助吗?

解决方案

在一个纯粹的功能的风格,则永远不会覆盖任何变量。

这是类似于将在物理时空。如果考虑世界3D,然后对象没有固定的位置 - 他们搬过来的时间。为了使数学承担对物理世界,因此,我们添加一个时间维度,并考虑在特定的时间各种属性的值。在此过程中,我们已经取得了我们的研究对象为常数。类似地,在编程,有通过与不可变值工作时也可以有一个概念简单。与在现实世界中的标识对象可以(在增加倍对象的状态),而不是作为发生改变的单个值被建模为不可变的值的序列。

当然如何值序列相关联,以“对象同一性”的细节可以稍微有毛。 Haskell有单子,让你的模型状态。 官能团反应编程是在造型对象,在全球拥有纯功能更新更字面的尝试,我认为是用于编程的非常有前途的方向。

我会注意到,Clojure的,不像哈斯克尔,是不是纯洁,如你所说,你可以更新变量。如果你只在高级别更新了几个变量,你可能仍然有很多的函数式编程的概念简单的好处。

其他提示

想必在OO世界里,你有一个循环,并一遍又一遍地响应请求再次修改这些银行账户。让我们假设你有帐户的完整组合,这些有型投资组合。然后在Haskell可编写一个纯函数

updatePortfolio :: Request -> Portfolio -> Portfolio

和你的主循环可能会从标准输入读取请求,并保持你的投资组合最新的。 (这个例子是没有多大用处,除非你可以写组合为好,但它是更简单的。)

readRequest :: IO Request  -- an action that, when performed, reads a Request with side effects

main :: Portfolio -> IO ()  -- a completely useless program that updates a Portfolio in response to a stream of Requests

main portfolio = do req <- readRequest
                    main (updatePortfolio req)

而现在我希望你看到的发生在你的可变状态:在一个典型的功能性程序,改变状态作为参数传递给函数。当状态changess,你犯了一个新的函数调用。电话是在尾部位置(你可以看一下“妥善尾调用”),因此它不使用任何额外的资源,而事实上,当编译器生成它生成一个循环的汇编代码,并且将指针保持到了不断变化的组合在寄存器中。

这是一个非常玩具的例子,但我希望它让你的函数式语言的味道一点。

所以...我该怎么办呢?覆盖任何变量被引用旧的银行账户?

如果是这样,具有在所述状态改变OOP方法的优点

让我们说任何的操作,您对结构做计算需要很长的时间,有事中途,你需要恢复到原来的结构或计算引发的错误。与解释你呈现给我的OO(使用一个参考,因为你可以有一个不变的面向对象的语言),除非足够的信息是从函数调用失败因为数据可能已损坏--IT的未知,并让提示失败厉害。在功能性方法,你肯定知道自己的原始数据结构是正确的 - 因为您最初制作的拷贝。

在多线程应用程序扩展了这种情况。我们可以确保没有其他人正在使用的数据结构我们是因为我们都有自己的版本。

此外,我们可以通过使用来自我们从复制其他结构数据节省空间。一个典型的例子是将一个元素增加到一个列表的头部的时候。如果我们有一个指针到第二元件,并且一个指向我们只能与所述第一的大小引用这两个列表的第一个元素(见下文)。没有永恒我们不能保证这一点。

        b__
           |  
a -> [6|] -+-> [5|] -> [4|] -> [3|] -> [2|] -> [1|x]

看看 Haskell,它是一种纯函数式语言——它没有任何重新分配,也没有其他副作用:为了进行IO,在 IO单子 构建它实际上取代了 真实世界 世界的新实例,例如,控制台中显示新文本。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top