module Test.Sloth.CoMonad ( CoPointed(..), CoMonad(..), (<<=) ) where import Control.Monad.Identity import Control.Monad.Writer class CoPointed f where extract :: f a -> a instance CoPointed Identity where extract (Identity x) = x class (Functor w,CoPointed w) => CoMonad w where duplicate :: w a -> w (w a) duplicate = extend id extend :: (w a -> b) -> w a -> w b extend f = fmap f . duplicate (<<=) :: CoMonad w => w a -> (w a -> b) -> w b m <<= f = extend f m instance CoMonad Identity where duplicate = Identity instance CoPointed m => CoPointed (WriterT w m) where extract = fst . extract . runWriterT