Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fundeps for constraint families

A lot of constraints seem to come together. Let's abstract these away.

type MonadNumState a m = (MonadState a m, Num a)

MonadNumState is just a constraint synonym, so I get the benefit of functional dependencies at every use, and can easily throw a MonadNumState a m into a context. Now, suppose I wish to abstract this into a constraint family:

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)
  ...

But now a is not a functional dependency. next is virtually unusable since a cannot be inferred. What can I do? Well, I could, of course, use a type family instead. MonadState is written using fundeps, but it should be easy to convert the fundeps to type families.

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

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

Guess not.

Foo.hs:25:3:
The RHS of an associated type declaration mentions type variable `s'
  All such variables must be bound on the LHS

What else might I be able to do? What I really want is to existentially quantify away s. I've not found any way to do that without explicit dictionary passing.

So, how do I get the benefit of fundeps for constraint families?

like image 232
James Koppel Avatar asked Jun 06 '13 10:06

James Koppel


1 Answers

You can consider using a standalone type family instead of an associated type

type family StateType (m:: * -> *)

Then you can define

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

instance (MonadState s m, s ~ StateType m) => MonadStateFamily m where
    get' = get

and use it on a concrete monad like this:

type instance StateType (State s) = s
getState :: State s s
getState = get' 
like image 158
mbenke Avatar answered Nov 15 '22 06:11

mbenke