Reputation: 3
data BTree a = Empty | Node a (BTree a) (BTree a) deriving Show
type Aluno = (Numero,Nome,Regime,Classificacao)
type Numero = Int
type Nome = String
data Regime = ORD | TE | MEL deriving Show
data Classificacao = Aprov Int| Rep| Faltou deriving Show
type Turma = BTree Aluno
I have this functions that counts how many "Alunos" have Regime TE.
My code:
numeroT :: Eq => Turma -> Int
numeroT Empty = 0
numeroT (Node (x,_,r,_) e d) = if (r==TE) then 1+((numeroT e)+(numeroT d))
else (numeroT e)+(numeroT d)
Can I not compare r
with TE? Getting Eq
error.
Upvotes: 0
Views: 2453
Reputation: 153
If you use the pattern matching of Haskell you can create:
numeroT :: Turma -> Int
numeroT Empty = 0
numeroT (Node (x,_,TE,_) e d) = (numeroT e) + (numeroT d) + 1
numeroT (Node (x,_,_,_) e d) = (numeroT e) + (numeroT d)
Upvotes: 0
Reputation: 120711
Haskell does not automatically assume that newly-defined data types allow equality-comparison. For some types this just isn't possible: for instance, you can in general not decide whether two functions are equal.
For simple ADTs like Regime
however, it is certainly possible. In doubt, you could define the Eq
instance yourself:
instance Eq Regime where
ORD==ORD = True
TE==TE = True
MEL==MEL = True
_ == _ = False
but to such a simple data type GHC can actually figure out alone how to do it: just add Eq
to the deriving
list.
data Regime = ORD | TE | MEL deriving (Show, Eq)
However, in Haskell, equality comparison is generally avoided: it tends to be clumsy and sometimes inefficient. Much more elegant is when you can pattern-match on constructors as Tohava showed: this lets you deconstruct a data structure and simultaneously decide what to do with the contents.
Upvotes: 4
Reputation: 5412
There are two solutions:
1) Allow Eq
data Regime = ORD | TE | MEL deriving (Show,Eq)
2) Use pattern-matching instead:
case r of
TE -> 1 + (numeroT e + numeroT d)
_ -> numeroT e + numeroT d
A shorter version of (2) is
(case r of
TE -> (+1)
_ -> id) $ numeroT e + numeroT d
Upvotes: 6