type Debug m a = ErrorT (OutputT String m) a debug :: Monad m => String -> Debug m () debug s = lift $ output s assert :: Monad m => Bool -> Debug m () assert True = return () assert False = wrong runDebug :: Monad m => Debug m a -> m (Maybe a,[String]) runDebug dp = runOutputT $ runErrorT dp fjas :: Debug IO () fjas = do debug "hej" q <- lift $ lift getLine debug q assert (1<0)