【问题标题】:boolen expression and side effects布尔表达式和副作用
【发布时间】:2020-10-03 23:22:41
【问题描述】:

我希望每个人都安全。

我正在学习 Haskell,发现 Haskell 中的函数没有副作用。我只是想知道在命令式语言中布尔表达式被认为是没有副作用的表达式,因为它们只返回 true 或 false(它们的主要效果)

谢谢!

【问题讨论】:

  • 函数可能会产生副作用,例如,如果您调用的函数写入文件、在数据库中插入记录等。

标签: haskell boolean-expression side-effects


【解决方案1】:

在命令式语言中,表达式通常会产生副作用。例如在 Python 中:

def f(x):
    print(x)
    return True

if f(2) or f(4):
    print(3)

因此,它会打印到标准输出通道,这是一个副作用。它还可以进行文件 I/O、在数据库中插入记录、执行网络 I/O、在列表中插入元素、创建进程以及其他形式的副作用。

无论表达式的类型如何,它通常都会产生副作用。在 safe Haskell 中,通常不能执行任何 I/O,除非您使用 IO,所以它是 IO Bool,而不是 Bool。此外,所有变量都是不可变的,因此您不能将元素添加到列表中,您可以构建一个新列表,但是对于“旧”列表的读者没有任何影响。

如果您当然指定它们返回TrueFalse,因此没有任何副作用,那么布尔表达式没有副作用,因为notandor 等通常也没有副作用。但问题是,在 Python(和其他命令式语言)中,不能根据返回类型判断函数是否有副作用。

函数没有副作用的想法使编译器可以进行很多优化。例如,在 Haskell 中,所有东西都是惰性求值的,这意味着除非你需要知道某物的价值,否则它不会被求值。这是可能的,因为没有副作用的评估函数的顺序并不重要。如果一个函数不能改变另一个函数可以访问的列表,那么它就不会影响该列表的结果。

此外,它还使并行运行变得更容易,因为没有副作用的函数不会影响另一个函数的结果,因此这两个函数可以由不同的内核评估。

但也许最有用的结果是它使程序非常模块化,并且不易出错。许多错误是由于函数对对象、数据库等进行更改而导致程序后面的函数没有预料到这些更改。例如,如果一个函数从数据库中删除了一条记录,那么下一个函数可能会在假设这条记录仍然存在的情况下工作。

【讨论】:

  • 所以基本上它与表达式无关,它与编程语言的规则有关,以确定哪些表达式有副作用,哪些没有。为什么 Haskell 或其他函数式编程语言不允许(基本上)任何副作用?它们在创建肤色和抽象方面不是很有用吗?
  • @ZeevKeane:没有任何副作用是有帮助的。例如,这意味着 Haskell 可以实现“自动”惰性编程:因此,程序员不必指定可以惰性完成的操作,编译器可以这样做,因为是否对其他函数的结果进行评估并不重要.
  • @ZeevKeane:更新了一些没有副作用的函数的优点。尤其是在 JavaScript 中,最近有一些有趣的函数式编程,以避免与这些副作用有关的错误。例如:opensource.com/article/17/6/functional-javascript
  • @ZeevKeane 是的,拥有由类型系统记录/强制执行的纯度意味着您不必依赖惯例/最佳实践/您的同事来做正确的事情。它允许您对其他代码的行为做出更安全的假设,而无需阅读它,从而减轻您的认知负担。
  • @ZeevKeane 一种可能的理解方式是:Haskell 并没有真正禁止副作用,我们总是可以返回 IO Bool 并假装是必要的。除此之外,Haskell 允许使用一种保证没有副作用的类型,即Bool。这样看来,命令式语言只有IO Bool,而在Haskell中我们可以在两者之间进行选择。甚至有人可能会争辩说,正因为如此,Haskell 给了我们更多的灵活性,而命令式语言限制程序员只能使用IO Bool,即使是纯函数也是如此。这是一个延伸,但从技术上讲是正确的。
猜你喜欢
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 2015-08-18
  • 1970-01-01
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多