Reputation: 2506
I have the an List which can contain just two kind of elements, Apple and Peach. I need to create a function which, given a list with those elements, returns the number of occurences of Apple in the list by using recursion.
Here is my attempt:
data Fruit = Apple | Peach
findFruit :: [Fruit] -> Int
findFruit [] = 0
findFruit (y:ys)
| y==Apple = 1+(findFruit ys)
| otherwise = findFruit ys
But it's not working. I suspect the issue is in the last instructions but I cannot really understand where as I'm still a Haskell newbie.
Here is the error log:
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.
Thank you for your help!
Upvotes: 3
Views: 635
Reputation: 71070
You can try for modularity and concept reuse with
import Data.Monoid
fruit a _ Apple = a -- case analysis for Fruit
fruit _ p Peach = p
countFruit = getSum . mconcat . map (fruit (Sum 1) (Sum 0))
(though it's not recursive).
Upvotes: 0
Reputation: 384
You can leave the data definition as it is and use pattern matching:
data Fruit = Apple | Peach
findFruit :: [Fruit] -> Int
findFruit [] = 0
findFruit (Apple:ys) = 1 + findFruit ys
findFruit (Peach:ys) = findFruit ys
Upvotes: 5
Reputation: 21757
You need to add deriving Eq
to your type constructor. That way, the notion of equality for your type will be automatically implemented and the == operator will be valid for use.
data Fruit = Apple | Peach deriving Eq
Upvotes: 3
Reputation: 42678
Your code is ok, but he does not know how to compare elements, so, just derive from eq as the compiler is telling you:
data Fruit = Apple | Peach deriving (Eq)
This way the compiler will have information about this data can be compared.
Upvotes: 1