I recently started a little hobby project, where I try to implement the trick-taking card-game Skat (for 3 players). To make it possible to have different kinds of players (like AI, network and local) playing together, I designed an interface using a typeclass Player:
class Monad m => Player p m | p -> m where
playerMessage :: Message answer -> p -> m (Either Error answer,p)
I use a StateT to wrap up those three players:
type PST a b c m x = StateT (Players a b c) m x
But now, I have to write a big pile of context in each type signature:
dealCards :: (Player a m, Player b m, Player c m, RandomGen g)
=> g -> PST a b c m (SomeOtherState,g)
How can I avoid writing this big context again and again?