为什么GHC说这两种类型不同?我怎样才能让他们变得一样?

时间:2015-03-07 22:50:56

标签: haskell

我定义了一个类:

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'相同。但是,我无法弄清楚如何做到这一点。任何帮助,将不胜感激。

1 个答案:

答案 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现在只代表Segmentb代表t {1}}。