【问题标题】:Mutual recursion in odd/even functions in haskellhaskell中奇/偶函数的相互递归
【发布时间】:2015-04-10 10:52:25
【问题描述】:

在 Graham Hutton 撰写的 “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 失败,加载模块:无。

为什么我会收到此消息?代码在语法上是过时的还是什么?

【问题讨论】:

    标签: haskell recursion ghci


    【解决方案1】:

    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 对其进行扩充。

    【讨论】:

    • 我认为这实际上是在查看自然数并使用Int 为方便起见。引入abs 可能没有意义。最好使用 Peano naturals:data Nat = Zero | Succ Nat,然后是 even Zero = True; even (Succ n) = odd n; odd Zero = False; odd (Succ n) = even n。
    • @dfeuer 为什么这没有意义呢?负整数是偶数,即使它可以被 2 整除,否则为奇数。虽然,您提供的实现及其模式匹配确实更符合问题的原始内容。
    • @DavidYoung,我收回了。如果您将整数表示为带符号的自然数,那么绝对值是一种非常合理的方法。但是对于Int,这没有有意义,它是 2 的补码二进制!
    【解决方案2】:

    我们自己的语言非常强大。我在教自己微积分时遇到了极限问题,直到我读到牛顿的一段中的一句话。当然是英文的。

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

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

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

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

    他们的工作方式是evens 工作。它构建输出列表。它获取列表中的第一项并使其成为输出列表的第一项或下一项。它使用列表的其余部分调用odds。 odds 只是将它收到的尾部返回给evens。

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

    evens 生成一个列表,其中大约有一半的项目被丢弃。 odds 只产生关键的丢弃。

    如果您将列表 [0,1,2,3,4] 提供给evens,它将返回从 0 开始的每隔一个项目,即 [0,2,4]。如果你给偶数列表 [1,2,3,4] 它返回 [1,3] 因为列表以奇数开头。无论evens 从哪里开始,它都会产生。

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 2011-04-01
      • 2016-06-13
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      相关资源
      最近更新 更多