【问题标题】:What is side effects in functional programming?函数式编程的副作用是什么?
【发布时间】:2016-08-15 13:54:14
【问题描述】:

我正在学习 Java 8,我看到一个与函数式编程相关的定义,即“使用仅纯函数创建的程序,无副作用允许”。

其中一个副作用是“就地修改数据结构”。

我不明白这一行,因为最后我们需要与数据库对话以存储、检索或更新数据。

修改数据库不是函数式意味着我们将如何在函数式编程中与数据库对话?

【问题讨论】:

  • 查找 IO Monad。
  • 在 Java 8 的上下文中,你不需要。如果这有好处,你就用函数式的方式表达操作,否则就求助于其他编程风格。

标签: functional-programming java-8


【解决方案1】:

“就地修改数据结构结构”意味着您直接操作输入数据结构(即列表)。 “纯函数”是指

  • 结果只是其输入的函数,而不是其他隐藏状态
  • 可以在同一输入上多次应用该函数,从而产生相同的结果。它不会改变输入。

在面向对象编程中,您定义对象的行为。行为可以是提供对对象状态的读访问、对它的写访问,或两者兼而有之。当组合不同关注点的操作时,可能会引入副作用。

例如一个堆栈,它是pop() 操作。每次调用都会产生不同的结果,因为它会改变堆栈的状态。

在函数式编程中,您将函数应用于不可变值。函数代表数据流,而不是状态变化。所以函数本身是无状态的。函数的结果要么是原始输入,要么是与输入不同的值,但绝不是修改后的输入。

OO 也知道函数,但这些函数并非在所有情况下都,例如排序:在非函数式编程中,您在原始数据结构中重新排列列表的元素(“就地”)。在 Java 中,这就是 Collections.sort()` 所做的。

在函数式编程中,您可以对输入值(列表)应用排序函数,从而生成具有排序值的新值(新列表)。函数本身没有状态,输入的状态也没有被修改。

所以概括一下:给定相同的输入值,对这个值应用一个函数会产生相同的结果值

关于数据库操作。数据库本身的内容代表一种状态,它是所有存储值、表等的组合(“快照”)。当然,您可以对这些数据应用一个函数来生成新数据。通常,您将操作结果存储回数据库,从而更改整个系统的状态,但这并不意味着您更改函数的状态或输入数据。再次重新应用该函数不会违反纯函数约束,因为您将数据应用于新的输入数据。但是将整个系统视为“数据结构”会违反约束,因为功能应用程序会更改“输入”的状态。

所以整个数据库系统几乎不能被认为是功能的,但是你当然可以以功能的方式对数据进行操作。

但是 Java 允许您同时执行这两种方法(OO 和 FP),甚至可以混合使用两种范式,因此您可以选择最适合您需求的任何方法。

或引用this answer

如果您有多种需求混合在一起,请混合您的范式。不要 限制自己只使用你的右下角 工具箱。

【讨论】:

    猜你喜欢
    • 2011-07-19
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    • 2010-11-10
    • 2010-09-13
    • 1970-01-01
    • 2010-11-04
    • 2010-12-27
    相关资源
    最近更新 更多