纯函数式编程语言?

3

什么是纯函数式语言?什么是纯函数式数据结构?我有点了解什么是函数式语言,但我不知道“纯”是什么意思。有人知道吗?能给我解释一下吗?谢谢!

2个回答

3
当函数式编程者提到“纯函数”这个概念时,他们是在提到引用透明性的概念。
引用透明性实际上是指在不改变程序行为的情况下进行值替换。
考虑一个将数字加2的函数:
let add2 x = x + 2

该程序中对 add2 2 的任何调用均可替换为值 4,而不改变任何行为。

现在考虑一下我们加入了一个 print

let add2 x =
    print x 
    x + 2

这个函数仍然返回与之前相同的结果,但是我们不能再进行值替换而不改变程序行为,因为add2 2会产生副作用,在屏幕上打印2
因此它不是引用透明的,因此是一个不纯的函数。
现在我们有了一个纯函数的好定义,我们可以将一个纯粹的函数式语言定义为一种几乎完全使用纯函数的语言。
注意:在纯函数式语言中仍然可以执行效果(例如打印到控制台),但这是通过将效果视为表示要执行的操作的值而不是作为某个函数中的副作用来完成的。然后将这些效果值组合成更大的程序行为集。
一个纯函数式数据结构就是一种被设计用于纯函数式语言中的数据结构。
由于使用函数改变数据结构会破坏引用透明性,所以每次添加或删除元素时我们需要返回一个新的数据结构。
有些特定类型的数据结构可以高效地实现这一点,共享先前副本的大量内存:单向链表和各种树形结构是最常见的例子,但还有许多其他类型。

这个_effect value_是否总是像Haskell中的IO一样是特殊类型? - user6445533
1
@ftor 是的,你需要一个特殊类型来处理这个。它可以像 Haskell 和一些流行的 Scala 实现中的 IO 一样,F# 使用 Async 处理异步效果,而 Purescript 则使用 Eff/Aff 处理同步/异步效果。 - TheInnerLight
@TheInnerLight 如果函数只执行一个数学函数且没有其他特性,那么它会被视为纯函数吗?在add2中,x不是纯数据结构对吧?你能给出一个纯数据结构的例子吗?我并不是很清楚。 - Jeff Yan
@JeffYan 不,x没有改变。在这种情况下,x绝对可以只是一个简单的不可变值,我们不会改变它,只需返回一个新值等于x+2。但我不认为这是一个纯函数数据结构,当我们谈论纯函数数据结构时,通常指的是由许多不可变值组成的集合。 - TheInnerLight

-2
今天使用的大多数功能性编程语言都不是纯净的,它们提供了与真实世界交互的方式。例如,很久以前 Haskell 有一些纯净的变体。
纯粹功能数据 = 持久数据(即不可变)。
纯函数 = 给定相同的输入始终产生相同的输出,并且不包含或受到副作用的影响。

2
纯函数式语言与现实世界的交互完全没有问题,这是一个有害的误解。这些语言只是不像大多数其他语言使用具有副作用的函数那样进行交互。Haskell对IO的处理方式涉及与现实世界的交互,而无需使用不纯的函数。 - TheInnerLight
1
@TheInnerLight - 你显然没有客观地阅读我的答案或者上下文。IO是附加组件还是核心语法的一部分与SO问题无关。 - Frank C.
当然是的。你的回答表明,如果一种语言与现实世界进行交互,那么它就不能被视为纯函数式的语言,我向你解释这个推论是错误的。报复性的负评也无法改变这一点。 - TheInnerLight

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接