"纯粹"在"纯函数式语言"中意味着什么?

Bob*_*y S 56 haskell functional-programming

Haskell被称为"纯函数式语言".

在这种情况下,"纯粹"意味着什么?这对程序员有什么影响?

Joe*_*sky 60

函数式语言中,您不能做任何有副作用的事情.

副作用意味着评估表达式会更改某些内部状态,以后会导致评估同一表达式产生不同的结果.在纯函数式语言中,您可以根据需要使用相同的参数来计算相同的表达式,并且它总是返回相同的值,因为没有要更改的状态.

例如,纯函数式语言不能有赋值运算符或输入/输出,尽管实际上,即使是纯函数式语言也经常调用不纯的库来进行I/O.

  • 仅仅调用不纯库来执行I/O的函数式语言并不纯粹.Haskell是纯粹的,它可以做I/O. 诀窍是将I/O"动作"包装为不可变值.因此"getChar"是"IO Char"类型的常量值,IO值可以组成更大的操作.该语言有一个名义解释器,用于处理"main"函数返回的IO值. (21认同)
  • 这是一个很好的答案,但我不确定它是最好的答案.因此,我很惊讶它迄今为止票数最多.从过去的经验来看,很多人都对像Haskell这样的语言被称为纯粹的函数式编程语言感到困惑,但仍然可以做一些有用的事情(例如I/O).这个答案没有澄清这一点. (16认同)
  • I/O仍然可以使用纯函数式语言 - 您可以将输入流视为字符列表,同样,您可以返回一个(可能是惰性评估的)字符列表作为输出. (11认同)
  • 另一方面,尽管超级明星级别和Spolsky先生的声誉值得尊敬,但我认为他在这里得到了一个至关重要的细节,并且那些投票他的回答是因为他写了这个,而不是因为它是正确的. (9认同)
  • 实际上,Haskell的早期版本的工作原理与此类似,尽管通用化允许更多的I/O操作,而不仅仅是读取和编写单个字符流. (3认同)
  • 我更喜欢,"在一种''纯'的功能语言中,你的功能不能告诉人们它有它们的副作用." 这在技术上是不真实的,这要归功于`seq`和`unsafePerformIO`,但这是一般的感觉.更好的是:"在''纯'函数式语言中,你可以用表达式的结果替换任何表达式,而不是改变程序的工作方式." 它有相同的警告,但它更积极地表达了"纯洁"有用的精神. (2认同)

eph*_*ent 32

"纯粹"和"功能性"是两个独立的概念,尽管没有另一个概念不是很有用.

纯表达式是幂等的:它可以被计算任意次数,每次都有相同的结果.这意味着表达式不能有任何可观察到的副作用.例如,如果一个函数改变了它的参数,在某个地方设置了一个变量,或者根据其输入之外的其他东西改变了行为,那么该函数调用就不是纯粹的.

函数式编程语言是函数是一流的语言.换句话说,您可以使用与操作所有其他第一类值完全相同的方便来操作函数.例如,能够使用"函数返回bool"作为"表示集合的数据结构"在函数编程语言中将是容易的.

函数式编程语言中的编程通常以大多数纯粹的方式进行,如果没有函数式编程语言启用的高阶函数操作,则很难完全纯粹.

Haskell是一种函数式编程语言,其中(几乎)所有表达式都是纯粹的; 因此,Haskell是一种纯函数式编程语言.

  • 优秀。您是我发现的少数几个了解 [不要混淆](http://stackoverflow.com/a/8357604/615784) _pure_(即 RT)和 FP 的人之一。 (3认同)
  • 我认为“纯表达式是幂等的”这句话是错误的。`f(x): x + 1` 是一个简单的增量函数,它是“纯”的,因为它没有任何副作用或状态。然而,它不是幂等的,因为`f(f(x)) != f(x)`。而像 `g(x): x - x` 这样的函数既是纯函数又是幂等的。因为它总是返回 0。 (2认同)

Chu*_*uck 24

纯函数是没有副作用的函数 - 它接受一个值并返回一个值.功能修改没有全局状态.纯函数语言是强制函数纯粹的语言.纯度有许多有趣的结果,例如评估可能是惰性的 - 因为函数调用没有任何目的而是返回一个值,那么如果你不打算使用它就不需要实际执行该函数它的价值.由于这一点,Haskell中常见的无限列表上的递归函数.

另一个结果是,评估函数的顺序无关紧要 - 因为它们不能相互影响,您可以按任何方便的顺序执行它们.这意味着并行编程带来的一些问题根本不存在,因为执行函数没有"错误"或"正确"的顺序.


Gil*_*il' 11

严格来说,函数式语言是一种函数式语言(即函数是第一类值的语言),其中表达式没有副作用.术语"纯功能语言"是同义词.

根据这个定义,Haskell不是一种纯函数式语言.您可以编写显示其结果,读取和写入文件,具有GUI等的程序的任何语言都不是纯粹的功能.因此,没有通用编程语言是纯函数式的(但是有一些有用的特定于域的纯函数式语言:它们通常可以某种方式被视为嵌入式语言).

有一种有用的放松感觉,像Haskell和Erlang这样的语言可以被认为是纯粹的功能,但像ML和Scheme这样的语言却不能.如果有一个相当大的,有用的和充分表征的子集,其中副作用是不可能的,那么语言就可以被认为是纯粹的功能.例如,在Haskell中,所有类型不是由其构建的程序IO或其他效果表示monad的程序都是无副作用的.在Erlang中,所有不使用IO诱导库或并发功能的程序都是无副作用的(这比Haskell案例更具延伸性).相反,在ML或Scheme中,副作用可以埋没在任何功能中.

从这个角度来看,Haskell的纯函数子集可以看作是处理每个monad内部行为的嵌入式语言(当然这是一个奇怪的视角,因为几乎所有的计算都发生在这个"嵌入式"子集中),并且Erlang的纯功能子集可以看作嵌入式语言处理本地行为.


Graham Hutton纯函数语言的主题略有不同,而且非常有趣:

有时,术语"纯功能"在更广泛的意义上也用于表示可能包含计算效果的语言,但不改变"功能"的概念(正如保留功能的基本属性这一事实所证明的那样). ,表达式的评估可以产生"任务",然后单独执行该任务以产生计算效果.评估和执行阶段以评估阶段不会损害表达式和函数的标准属性的方式分开.例如,Haskell的输入/输出机制就是这种.

即在Haskell中,函数具有类型a -> b并且不具有副作用.类型的表达式IO (a -> b)可能有副作用,但它不是一个函数.因此在Haskell函数中必须是纯函数,因此Haskell纯粹是函数式的.

  • IO函数的类型略有不同`a - > IO b`,实际上它只是一个返回IO包装值的函数. (2认同)