{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-} import Control.Monad.State.Lazy class Monad m => Streaming a m where writeS :: [a] -> m () class Monad m => Counting m where incC :: m () -- write :: (Streaming a m, Counting m) => [a] -> m () write x = do { writeS x; incC } instance Monad m => Streaming a (StateT [a] m) where writeS y = do x <- get put (x ++ y) instance Monad m => Counting (StateT Int m) where incC = do x <- get put (x + 1) foo = runStateT 0 $ runStateT "" $ write "message"