2015-02-08 44 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)