如何在Haskell中将变量与数据类型进行比较?

时间:2015-02-08 16:47:00

标签: haskell haskell-platform

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错误。

3 个答案:

答案 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)
相关问题