【发布时间】:2012-01-22 20:05:37
【问题描述】:
我使用类型上下文为我创建的数据类型进行实例声明。
data Set a = Insert a (Set a) | EmptySet
instance (Show a) => Show (Set a) where
show x = "{" ++ show' x ++ "}" where
show' (Insert x EmptySet) = show x
show' (Insert x xs) = show x ++ ", " ++ show' xs
instance Eq a => Eq (Set a) where
(Insert x xs) == (Insert y ys) = (x == y) && (xs == ys)
所以现在,我必须将 Eq 类型上下文添加到我定义的所有使用我的 Set 类型的函数中,就像这样,否则我会收到类型错误:
memberSet::Eq a =>a->Set a->Bool
memberSet _ EmptySet = False
memberSet x (Insert y ys)
| x == y = True
| otherwise = memberSet x ys
subSet::Eq a=>Set a->Set a->Bool
subSet EmptySet _ = True
subSet (Insert a as) bs
| memberSet a bs = subSet as bs
| otherwise = False
我得到的错误看起来像:
No instance for (Eq a)
arising from a use of `=='
In the expression: (x == y)
In a stmt of a pattern guard for
an equation for `memberSet':
(x == y)
In an equation for `memberSet':
memberSet x (Insert y ys)
| (x == y) = True
| otherwise = memberSet x ys
Failed, modules loaded: none.
这甚至意味着什么?为什么我会收到此错误?我想一旦我做了实例声明,Haskell 将能够自动验证在我的函数 "memberSet" 和 "subSet" 中被 "==" 比较的东西会被自动检查为 "Eq?"
为清楚起见进行编辑:
我的问题是我不明白为什么“memberSet”和“subSet”需要类型上下文。如果我像这样删除它们,它不会编译。
memberSet::a->Set a->Bool
memberSet _ EmptySet = False
memberSet x (Insert y ys)
| x == y = True
| otherwise = memberSet x ys
subSet::Set a->Set a->Bool
subSet EmptySet _ = True
subSet (Insert a as) bs
| memberSet a bs = subSet as bs
| otherwise = False
【问题讨论】:
-
你给我的代码类型检查。你漏掉了什么?
-
我怀疑一些涉及范围或名称的相当微妙的错误,因为给出的代码看起来不错。
-
我的问题不清楚。代码按原样编译。我想知道为什么它不能使用我将编辑的“成员集”和“子集”上的类型上下文进行编译。