许多限制似乎汇集在一起。让我们把这些抽象出来。
type MonadNumState a m = (MonadState a m, Num a)
MonadNumState
只是一个约束同义词,所以我在每次使用时都能从函数依赖中受益,并且可以轻松地将 aMonadNumState 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
不是功能依赖。next
几乎无法使用,因为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
。如果没有明确的字典传递,我还没有找到任何方法来做到这一点。
那么,我如何为受限制的家庭获得fundeps的好处?