我开始阅读一些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))
现在,如果我们执行z
和w
,我们会得到:
z(5) //gives 3*5+3=18
w(5) //gives (5+3)*3=24
就是这样,我想我误解了他们所说的承诺保证。任何人都可以向我解释一下吗?
答案 0 :(得分:8)
将x(y(a))
与y(x(a))
进行比较时,这两个表达式并不相同,因为x
和y
不会在每个表达式中使用相同的参数进行调用。在第一个表达式中x
使用参数y(a)
调用,y
使用参数a
调用。而第二个y
使用x(a)
而不是a
进行调用,而其参数和x
则使用a
进行调用,而不是y(a)
。所以:不同的论点,(可能)不同的结果。
当人们说订单无关紧要时,他们的意思是在以下代码中:
a = f(x)
b = g(y)
您可以切换a
和b
的定义,而不会影响其值。也就是说f
之前调用g
或反之亦然没有区别。以下代码显然不是这样:
a = getchar()
b = getchar()
如果您在这里切换a
和b
,它们的值也会切换,因为getchar
每次调用时都会返回一个(可能)不同的字符。因此,纯函数式语言不能具有与getchar
完全相同的函数。