【问题标题】:Haskell even number iterationHaskell 偶数迭代
【发布时间】:2017-01-04 20:07:03
【问题描述】:

我正在尝试从整数列表中删除所有奇数。但是遇到了一些问题(我是个新手),这是我的代码:

 evenfunc :: [Int] -> [Int]
 evenfunc li =
        x = head li
        y = tail li
        if even x
          then x : myevenfunc xs --take head an pass tail recursively
        else
          drop x li : myevenfunc xs --drop head from list and pass tail recursively

在尝试运行时,它给了我一个“输入 '='' 解析错误消息。

我在这里做错了什么?

【问题讨论】:

标签: haskell recursion iteration fold


【解决方案1】:

当然应该首选使用filter 的给定解决方案,但递归版本也可能具有指导意义:

evenfunc :: [Int] -> [Int]
evenfunc [] = []
evenfunc (x:xs) = if even x then x : tail else tail where
    tail = evenfunc xs  

第一行evenfunc [] = [] 处理基本情况——空列表。您在解决方案中遗漏了这一点,如果您在空列表中调用 head,则会出现异常。

第二行使用模式解构列表:x 是头部,xs 是尾部。然后我们使用if 就像在命令式语言中一样,不同之处在于它返回一个值(因此它实际上更接近于Java 等中的三元运算符x ? y : z)。为了避免重复,我们在where 子句中定义了一个子表达式tail。如果在定义之前使用东西对你来说很奇怪,你可以使用 let 代替,它的工作原理类似。当然,计算tail意味着执行递归调用。

【讨论】:

    【解决方案2】:

    Haskell 不是一种命令式语言,您可以在其中订购语句,但您可以通过使用 let 将值绑定到标识符来实现您的方法:

    f :: Int -> Int
    f x = let y = x + 5 in y * 3
    

    但是即使使用这个你的函数也有一些问题:

    • 你的递归调用是错误的(使用evenfunc
    • 您对drop 的使用可能是错误的
    • 你永远不会在任何地方定义xs

    总而言之,最好使用库函数来改造您的方法。 filter 完全符合您的要求:

    evenfunc list = filter even list
    

    或者,甚至:

    evenfunc = filter even
    

    【讨论】:

    • 谢谢 - 如果我想映射列表并删除元素怎么办?您将如何构建它?
    • @ronaldmurphy 这正是filter 的用途。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    相关资源
    最近更新 更多