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

How i can compare a variable with a data type in Haskell?

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 政权。

我的代码:

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

有两种解决方法:

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

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 展示的那样在构造函数上进行模式匹配时:这使您可以解构数据结构并同时决定如何处理内容。

如果您使用 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)