odd/even 中的相互递归在 haskell 中起作用

Mutual recursion in odd/even functions in haskell

在 Graham Hutton 的 "Programming in Haskell" 的第 6 章中有一个名为“6.5 相互递归”的部分,其中包含以下示例:

even :: Int -> Bool
even 0       = True
even (n + 1) = odd n

odd :: Int -> Bool
odd 0       = False
odd (n + 1) = even n

我想尝试一下。我把代码放在Hof.hs文件里,运行ghci(版本7.8.3),输入

:l Hof.hs

并收到以下错误消息

Hof.hs:3:7:模式解析错误:n + 1
失败,已加载模块:none。

为什么我会收到这条消息?代码在语法上是否过时?

n + k patterns have been removed 来自 Haskell,并且不再可用。改为这样写:

even :: Int -> Bool
even 0 = True
even n = odd (n - 1)

odd :: Int -> Bool
odd 0 = False
odd n = even (n - 1)

请注意,此函数对于负输入会严重失败,因此您可能希望使用 abs 来扩充它。

我们自己的语言很强大。在自学微积分时,我在极限方面遇到了困难,直到我读了牛顿的一段话中的一句话。当然是英文的。

首先,您关于未使用或不需要索引的说法是正确的。

其次,代码不知道偶数或奇数之间的区别,你再次质疑它是正确的。

最后,我稍微修改了这些以在我的实现中正常工作。

     evens [x] = [x];    evens (x:xs) = x:odds xs
     odds  [x] = [];      odds (_:xs) =  evens xs

它们的工作方式是 evens 完成工作。它构建输出列表。它获取列表的第一项,并使其成为输出列表的第一项或下一项。它用列表的其余部分调用 oddsodds 简单地 returns 它收到的尾巴 evens.

像 tail 一样,它会丢弃收到的第一项。

evens 生成一个列表,其中大约一半的项目被丢弃。 odds 除了临界丢弃之外什么都不产生。

如果您给 evens 列表 [0,1,2,3,4],它 returns 每隔一个以 0 开头的项目,即 [0,2,4]。如果您将列表 [1,2,3,4] 设为偶数,则它 returns [1,3] 因为列表以奇数开头。 evens 从哪里开始,它就产生什么。

尝试使用 [1,1,1,1,1] 或 "bcdefg"

对函数所做的修改反映了每个函数分别对其余元素执行的操作。 odds 丢弃它,evens 将它附加到输出列表的末尾。

这两个函数只有在给定以偶数开头的列表时才能正常工作。如果给定一个奇数列表,它们将反向工作。

这是一个函数,它会根据指定的起始编号和以指定的结束编号结束生成偶数或奇数列表。

eo s e = [s,s+2..e]