在函数式编程中切换顺序后保证输出的相同性

时间:2017-02-05 17:43:28

标签: haskell functional-programming

我开始阅读一些Haskell的文档,这是一个我不理解的基本概念。我也在其他地方读过它,但我想一劳永逸地理解它。

在许多讨论功能编程的地方,我一直在阅读如果您使用的功能是纯粹的(没有副作用,并且在每次通话时对相同的输入给出相同的响应)那么您可以切换顺序在编写它们时它们被调用,保证无论顺序如何,这个组合调用的输出都将保持不变。

例如,这里是an entry from the Haskell Wiki

  

Haskell是一种纯语言,意味着任何结果   函数调用完全由其参数决定。伪功能   像C中的rand()或getchar(),它们在每个上都返回不同的结果   调用,根本不可能在Haskell中编写。而且,哈斯克尔   功能不具备副作用,这意味着它们无法起作用   对现实世界"的任何改变,比如改变文件,写入   屏幕,打印,通过网络发送数据等。这两个   限制在一起意味着任何函数调用都可以替换为   使用相同参数的上一次调用的结果,以及   语言保证所有这些重新安排都不会改变   节目结果!

但是当我摆弄这个想法时,我可以很快想到与上述陈述相矛盾的例子。例如,让我说我有两个函数(我将使用伪代码而不是Haskell):

x(a)->a+3

y(a)->a*3


z(a)->x(y(a))

w(a)->y(x(a))

现在,如果我们执行zw,我们会得到:

z(5) //gives 3*5+3=18

w(5) //gives (5+3)*3=24

就是这样,我想我误解了他们所说的承诺保证。任何人都可以向我解释一下吗?

1 个答案:

答案 0 :(得分:8)

x(y(a))y(x(a))进行比较时,这两个表达式并不相同,因为xy不会在每个表达式中使用相同的参数进行调用。在第一个表达式中x使用参数y(a)调用,y使用参数a调用。而第二个y使用x(a)而不是a进行调用,而其参数和x则使用a进行调用,而不是y(a)。所以:不同的论点,(可能)不同的结果。

当人们说订单无关紧要时,他们的意思是在以下代码中:

a = f(x)
b = g(y)

您可以切换ab的定义,而不会影响其值。也就是说f之前调用g或反之亦然没有区别。以下代码显然不是这样:

a = getchar()
b = getchar()

如果您在这里切换ab,它们的值也会切换,因为getchar每次调用时都会返回一个(可能)不同的字符。因此,纯函数式语言不能具有与getchar完全相同的函数。