How can I turn Maybe-Transformer MaybeT into an instance of MonadWriter?

I'm trying to build MaybeT-Transformer Monad, based on an example in Real World Haskell, chapter of Monad Transformers:

data MaybeT ma = MaybeT { runMT :: m (Maybe a) } instance (Monad m) => Monad (MaybeT m) where m >>= f = MaybeT $ do a <- runMT m case a of Just x -> runMT (fx) Nothing -> return Nothing return a = MaybeT $ return (Just a) instance MonadTrans MaybeT where lift m = MaybeT $ do a <- m return (Just a) 

This works fine, but now I want to make MaybeT an instance of MonadWriter:

 instance (MonadWriter wm) => MonadWriter w (MaybeT m) where tell = lift . tell listen m = MaybeT $ do unwrapped <- listen (runMT m) return (Just unwrapped) 

The story is fine, but I can’t get the listening function correctly. The best I could come up with after 1 1/2 days of the origami constructor is the one you see above: the expandable should be a tuple (maybe a, w) and what I want to wrap in Maybe-Type and put it all in empty MonadWriter.

But the compiler complains:

 Occurs check: cannot construct the infinite type: a = Maybe a When generalising the type(s) for `listen' In the instance declaration for `MonadWriter w (MaybeT m)' 

What am I missing?

+4
source share
1 answer

listen has a signature like

  ma -> m (a, w) 

i.e.

  MaybeT ma -> MaybeT m (a, w) 

But MaybeT $ listen (runMT m) >>= return . Just MaybeT $ listen (runMT m) >>= return . Just has a signature like

  MaybeT ma -> MaybeT m (Maybe a, w) 

therefore, an error of infinite type arises. You need to convert this unwrapped :: (Maybe a, w) to Maybe (a, w) to continue:

 listen m = MaybeT $ do (val, wr) <- listen (runMT m) case val of Nothing -> return Nothing Just x -> return (Just (x, wr)) 

(BTW, there is a MaybeT implementation at http://www.haskell.org/haskellwiki/New_monads/MaybeT .)

+6
source

Source: https://habr.com/ru/post/1308562/


All Articles