Alexandre Mirra
Alexandre Mirra

Reputation: 3

How i can compare a variable with a data type in Haskell?

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

Answers (3)

sverien
sverien

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

leftaroundabout
leftaroundabout

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

tohava
tohava

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

Related Questions