3

我的问题是关于如何将等式约束放入关联的类型约束(即类型约束)

具体用例是一个由部分应用类型参数化的类:

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~Maybe b',所以我不能将此约束移至 f 的类型签名。b 不在任何地方的实例范围内(也许这就是 GHC 所抱怨的),但没有必要这样做。功能

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

是有效的,我看不出为什么我不能用约束来做到这一点。顶级约束以及关联的类型约束都会出现此问题。

可能相关的是这个问题,除了我需要与不在范围内的变量相等。

4

1 回答 1

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真的是 kind 类型变量*而不是 kind类型变量* -> *吗?如果是后者,您只需要

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

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

于 2012-09-25T03:14:27.233 回答