2015-02-08 3 views
0
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 

У меня есть эти функции, которые подсчитывают, сколько «Alunos» имеет режим TE.Как я могу сравнить переменную с типом данных в Haskell?

Мой код:

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) 

Могу ли я не сравнить r с TE? Получение ошибки Eq.

+2

В будущем, пожалуйста добавьте сообщение об ошибке при всем вы столкнетесь с проблемой, как это. «Ошибка Eq» может быть много совершенно другой. – leftaroundabout

+0

Спасибо за подсказку. Мой первый вопрос. Сожалею. –

ответ

6

Есть два решения:

1) Разрешить уравнение

data Regime = ORD | TE | MEL deriving (Show,Eq) 

2) Используйте шаблон сопоставления вместо:

case r of 
    TE -> 1 + (numeroT e + numeroT d) 
    _ -> numeroT e + numeroT d 

Более короткий вариант (2)

(case r of 
    TE -> (+1) 
    _ -> id) $ numeroT e + numeroT d 
+0

Спасибо: D Сработало! –

+1

@AlexandreMirra Если этот ответ решил вашу проблему, не забудьте принять его, нажав на отметку ниже подсчета голосов. После того, как вы собрали 15 репутационных очков на этом сайте, вы также сможете перенаправить ответы. – Jubobs

+1

Проще, я думаю, написать '(case r of TE -> 1; _ -> 0) + ...'. – amalloy

4

Haskell делает не автоматически предполагают, что вновь определенные типы данных позволяют сравнивать равенство. Для некоторых типов это просто невозможно: например, вы можете вообще не решить, равны ли две функции.

Для простых ADT, например Regime, это, безусловно, возможно. При возникновении сомнений, вы можете определить Eq экземпляра себя:

instance Eq Regime where 
    ORD==ORD = True 
    TE==TE = True 
    MEL==MEL = True 
    _ == _ = False 

но такого простого типа данных GHC может на самом деле выяснить, в одиночку, как это сделать: просто добавьте Eq в deriving список.

data Regime = ORD | TE | MEL deriving (Show, Eq) 

Однако, в Haskell, сравнение равенства, как правило, избегать: он имеет тенденцию быть неуклюжим и иногда неэффективным. Гораздо более элегантным является то, когда вы можете сопоставлять шаблоны с конструкторами, как показал Тохава: это позволяет вам деконструировать структуру данных и одновременно решать, что делать с содержимым.

+0

Большое спасибо. Я только что использовал: instance Eq Regime где: И моя функция просто сработала;). спасибо –

0

Если вы используете pattern matching в Haskell вы можете создать:

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) 
Смежные вопросы