我定义了一个类:
class Query a where
filter :: a -> (b -> Bool) -> [b]
ifilter :: a -> (b -> Bool) -> [(b, Int64)]
我有一个用户定义的类型:
data Segment a = Segment {
extents :: [Extent],
array :: [a]
} deriving(Eq, Show)
最后,我尝试将Segment作为Query的一个实例:
instance Query (Segment a) where
filter = filterSegment
ifilter = ifilterSegment
函数filter和ifilter都采用(Segment a)和函数(a-> Bool)并返回[a]或[(a,Int64)]。
但是,我收到以下错误:
Couldn't match type `a' with `b'
`a' is a rigid type variable bound by
the instance declaration at src/Store/DataColumn.hs:19:10
`b' is a rigid type variable bound by
the type signature for filter :: Segment a -> (b -> Bool) -> [b]
at src/Store/DataColumn.hs:20:3
Expected type: Segment a -> (b -> Bool) -> [b]
Actual type: Segment a -> (a -> Bool) -> [a]
In the expression: filterSegment
In an equation for `filter': filter = filterSegment
In the instance declaration for `Query (Segment a)'
Couldn't match type `a' with `b'
`a' is a rigid type variable bound by
the instance declaration at src/Store/DataColumn.hs:19:10
`b' is a rigid type variable bound by
the type signature for
ifilter :: Segment a -> (b -> Bool) -> [(b, Int64)]
at src/Store/DataColumn.hs:21:3
Expected type: Segment a -> (b -> Bool) -> [(b, Int64)]
Actual type: Segment a -> (a -> Bool) -> [(a, Int64)]
In the expression: ifilterSegment
In an equation for `ifilter': ifilter = ifilterSegment
In the instance declaration for `Query (Segment a)'
我不确定我在这里缺少什么。我确实希望(段a)中的'a'与(a-> Bool),[a]和[(a,Int64)]中的'a'相同。但是,我无法弄清楚如何做到这一点。任何帮助,将不胜感激。
答案 0 :(得分:16)
您对类型类的定义对b
的含义没有限制,这意味着应该允许用户为他想要的b
选择任何类型。当然,你的实例定义不允许这样做,这就是它被拒绝的原因。
你想说的是“a是在类型b上进行参数化的,那就是我想要使用的类型b”。这就是你怎么说的:
class Query a where
filter :: a b -> (b -> Bool) -> [b]
然后你写instance Query Segment
而不是instance Query (Segment t)
,因为类型类定义中的a
现在只代表Segment
而b
代表t
{1}}。