Haskell偶数迭代

时间:2016-08-28 20:04:56

标签: haskell recursion iteration fold

我试图从整数列表中删除所有奇数..但是有一些问题(我是一个新手),这是我的代码:

 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

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

我在这里做错了什么?

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

当然,使用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)。为了避免重复,我们在tail子句中定义了一个子表达式where。如果在定义它们之前使用它们很奇怪,则可以使用let代替它,它的工作方式类似。当然,计算tail意味着执行递归调用。