我有一个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.
感谢您的帮助!
答案 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))
(虽然它不是递归的)。