使用Haskell中的递归在List中查找事件

时间:2015-12-28 07:55:41

标签: haskell recursion

我有一个List,它只能包含两种元素, Apple Peach 。我需要创建一个函数,给定带有这些元素的列表,使用递归返回列表中 Apple 的出现次数。

这是我的尝试:

data Fruit = Apple | Peach
findFruit :: [Fruit] -> Int

findFruit [] = 0

findFruit (y:ys)
    | y==Apple = 1+(findFruit ys)
    | otherwise = findFruit ys

但它没有用。我怀疑这个问题是在最后的说明中,但我真的不明白我在哪里仍然是Haskell的新手。

以下是错误日志:

Main.hs:7:8:
    No instance for (Eq Fruit) arising from a use of ‘==’
    In the expression: y == Apple
    In a stmt of a pattern guard for
                   an equation for ‘findFruit’:
      y == Apple
    In an equation for ‘findFruit’:
        findFruit (y : ys)
          | y == Apple = 1 + (findFruit ys)
          | otherwise = findFruit ys
Failed, modules loaded: none.

感谢您的帮助!

4 个答案:

答案 0 :(得分:4)

您可以保留数据定义并使用模式匹配:

data Fruit = Apple | Peach

findFruit :: [Fruit] -> Int
findFruit []         = 0
findFruit (Apple:ys) = 1 + findFruit ys
findFruit (Peach:ys) = findFruit ys

答案 1 :(得分:2)

您需要将deriving Eq添加到类型构造函数中。这样,您的类型的相等概念将自动实现,并且==运算符将有效使用。

data Fruit = Apple | Peach deriving Eq

答案 2 :(得分:0)

您的代码没问题,但他不知道如何比较元素,因此,只需从编译器告诉您的eq派生出来:

data Fruit = Apple | Peach deriving (Eq)

这样编译器就可以比较有关此数据的信息。

答案 3 :(得分:0)

您可以尝试使用

进行模块化和概念重用
import Data.Monoid

fruit a _ Apple = a    -- case analysis for Fruit 
fruit _ p Peach = p

countFruit = getSum . mconcat . map (fruit (Sum 1) (Sum 0))

(虽然它不是递归的)。