我是Haskell的初学者,现在发现了一种我不太了解的行为。
我正在读一本书,其中有一项练习是写一个函数,该函数删除给定char的第一个匹配项,并使数组的其余部分保持不变。
经过几次尝试,我想出了可以运行的代码,但我不知道为什么。代码如下:
removeFirst r [s]
| s == r = []
| otherwise = [s]
removeFirst r (x:xs)
| r /= x = x : removeFirst r xs
| otherwise = xs
能否请任何人向我解释为什么这个电话
removeFirst 'a' "strange"
工作而不是返回xs,因此是“nge”?为什么会发生串联,并且代码看起来应该如何获得“nge”?
最佳答案
让我们只考虑递归情况:
removeFirst r (x:xs)
| r /= x = x : removeFirst r xs
| otherwise = xs
调用顺序为:
removeFirst 'a' "strange"
:自
'a' /= 's'
以来,其结果为's' : removeFirst 'a' "trange"
removeFirst 'a' "trange"
:自
'a' /= 't'
以来,其计算结果为't' : removeFirst 'a' "range"
但是我们以前的调用中已经有了
's':
,所以我们总共得到了's': ('t' : removeFirst 'a' "range")
removeFirst 'a' "range"
:自
'a' /= 'r'
以来,其计算结果为'r' : removeFirst 'a' "ange"
。但是我们以前的调用中已经有了
's':'t':
,所以我们总共得到了's' : ('t' : ('r' : removeFirst 'a' "ange")
removeFirst 'a' "ange"
:由于
'a' /= 's'
是false
,因此其求值为xs
,在这种情况下为"nge"
。但是我们以前的调用中已经有了
's':'t':'r':
,因此我们总共得到's':'t':'r':"nge"
。 更新
@Zeta在Pastebin上提供了评估术语的不错摘要,我毫不客气地在这里包括:
removeFirst 'a' "strange"
= 's' : removeFirst 'a' "trange"
= 's' : 't' : removeFirst 'a' "range"
= 's' : 't' : 'r' : removeFirst 'a' "ange"
= 's' : 't' : 'r' : "nge"
= "strnge"