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。
我的代码:
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
错误。
答案 0 :(得分:6)
有两种解决方案:
1)允许Eq
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
答案 1 :(得分:4)
Haskell不会自动假设新定义的数据类型允许进行相等比较。对于某些类型,这是不可能的:例如,您通常不能确定两个函数是否相等。
对于像Regime
这样的简单ADT,它肯定是可能的。有疑问,您可以自己定义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中,通常会避免相等比较:它往往是笨拙的,有时效率低下。当你可以像Tohava所展示的那样在构造函数上进行模式匹配时更加优雅:这可以让你解构数据结构并同时决定如何处理内容。
答案 2 :(得分:0)
如果你使用Haskell的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)