约束种类中的等式约束

时间:2012-09-25 01:32:19

标签: haskell types type-kinds

我的问题是关于如何在相关类型约束中放置等式约束(即类型约束)

特定用例是由部分应用类型参数化的类:

class Foo c where -- c has kind *->*->*
  type Ctx c m r :: Constraint
  f :: (Ctx c m r) => c m r -> c m r

在特定情况下,我想写一下:

data Bar m r = ...

instance Foo Bar where
   type Ctx Bar m r = (m~Maybe b) 
   -- m must be a Maybe, I don't care what its parameter is
   f = ...

然而,GHC抱怨:'不在范围内:输入变量b'。 我没有看到任何其他方式来表达这种约束。并非每个实例都需要'm~Mear b',所以我无法将此约束移动到f的类型签名。 b不在任何地方的范围内(也许这就是GHC所抱怨的),但没有必要这样做。功能

f :: (a ~ Maybe b) => a -> a -> a

是有效的,我认为没有理由不能用约束来做到这一点。顶级约束以及相关的类型约束会出现此问题。

可能相关的是this问题,除了我需要与范围内的变量NOT相等。

1 个答案:

答案 0 :(得分:2)

这是表达此约束的另一种方式:

class IsMaybe m {- where ...whatever operations you need to do on Maybe values -}
instance IsMaybe (Maybe b) {- where ...implement those operations -}
instance Foo Bar where
    type Ctx Bar m r = IsMaybe m

但是,考虑到Haskell的命名约定,如果这实际上是你想要的,我会感到很惊讶 - m实际上是类*的类型变量而不是* -> *类型变量}?如果是后者,你只需要

instance Foo Bar where
    type Ctx Bar m r = m~Maybe

...可能是Foo的类声明中的一种注释。