Haskell 约束族的Fundeps

Haskell 约束族的Fundeps,haskell,typeclass,Haskell,Typeclass,很多约束似乎都在一起。让我们把这些抽象出来 type MonadNumState a m = (MonadState a m, Num a) MonadNumState只是一个约束同义词,因此我在每次使用时都会受益于函数依赖关系,并且可以轻松地将MonadNumState a m抛出到上下文中。现在,假设我希望将其抽象为约束族: class Iterator t where type MonadIter t a m :: Constraint next :: (MonadIter t

很多约束似乎都在一起。让我们把这些抽象出来

type MonadNumState a m = (MonadState a m, Num a)
MonadNumState
只是一个约束同义词,因此我在每次使用时都会受益于函数依赖关系,并且可以轻松地将
MonadNumState a m
抛出到上下文中。现在,假设我希望将其抽象为约束族:

class Iterator t where
  type MonadIter t a m :: Constraint
  next :: (MonadIter t a m) => m t
  ...

instance Iterator Foo where
  type MonadIter Foo a m = (MonadState a m, Num a)
  ...

instance Iterator Bar where
  type MonadIter Bar a m = (MonadRandom m, MonadSplit a m, RandomGen a)
  ...
但是现在
a
不是一个函数依赖项<代码>下一步实际上是不可用的,因为无法推断出
a
。我能做什么?当然,我可以用类型族来代替
MonadState
是使用fundeps编写的,但是将fundeps转换为类型族应该很容易

instance (MonadState s m) => MonadStateFamily m where
  type St m = s
  get' = get
  ...

instance (MonadStateFamily m) => MonadState (St m) m where
  get = get'
  ...
我想不是

Foo.hs:25:3:
The RHS of an associated type declaration mentions type variable `s'
  All such variables must be bound on the LHS
我还能做什么?我真正想要的是以存在的方式量化
s
。如果没有明确的字典传递,我找不到任何方法来实现这一点


<> P>那么,如何得到约束族的项目收益?

< P>可以考虑使用独立类型族而不是关联类型

type family StateType (m:: * -> *)
然后你可以定义

class MonadStateFamily m where
    get' :: m (StateType m)

instance (MonadState s m, s ~ StateType m) => MonadStateFamily m where
    get' = get
在混凝土单子上使用,如下所示:

type instance StateType (State s) = s
getState :: State s s
getState = get'