2015-02-08 55 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」有Regime 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) 

我不能用TE比較r?獲取Eq錯誤。

+2

在未來,請當你遇到這樣的問題,增加了整個錯誤消息。 「'Eq'錯誤」可能是很多完全不同的東西。 – leftaroundabout 2015-02-08 17:08:52

+0

感謝您的提示。我的第一個問題。抱歉。 – 2015-02-08 17:52:56

回答

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它工作! – 2015-02-08 17:38:30

+1

@AlexandreMirra如果此答案解決了您的問題,請不要忘記通過點擊投票計數下面的標記來接受它。一旦你在這個網站上搜集了15個聲望點,你也可以提出答案。 – Jubobs 2015-02-08 18:47:14

+1

我認爲,寫'(TE的情況r - > 1; _ - > 0)+ ...'更簡單。 – amalloy 2015-02-08 19:48:47

4

Haskell確實不會自動假定新定義的數據類型允許相等比較。對於某些類型而言,這是不可能的:例如,您通常可以不確定兩個函數是否相等。

但是,對於像Regime這樣的簡單ADT,這當然是可以的。如有疑問,您可以自己定義Eq實例:

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

,但這樣的簡單數據類型GHC居然能想出單獨如何做到這一點:只需添加Eqderiving列表。

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

然而,在Haskell,相等比較通常避免:它往往是笨拙和有時低效的。 Tohava表示:在構造函數上進行模式匹配時,更優雅的是,這可以讓您解構數據結構並同時決定如何處理內容。

+0

非常感謝。我剛剛使用: 實例Eq制度其中: 而我的功能剛剛工作;)。謝謝 – 2015-02-08 17:18:18

0

如果使用哈斯克爾的pattern matching您可以創建:

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)