[<<][haskell][>>][..]
Sat Sep 1 09:20:21 EDT 2018

Monad transformers

EDIT: See bottom.  This is all a misunderstanding.

How to create a monad transformer?  E.g. instead of using one of the
standard ones directly, what about abstracting away an effect and
wrapping it only as part of a stack?

https://blog.jakuba.net/2014/07/22/building-monad-transformers-part-1.html

Trying to abstract the assembler as a monad transformer.  



-- Assembler.
data Asm i m t = Asm [i] (m t) -- deriving (Functor, Applicative)

instance Functor m => Functor (Asm i m) where
  fmap f (Asm is mv) = Asm is $ fmap f mv
instance Applicative m => Applicative (Asm i m) where
  pure v = Asm [] $ pure v
  (Asm is mf) <*> (Asm is' mv) = undefined
instance Monad m => Monad (Asm i m) where
  (Asm is' mv) >>= f = undefined
  

Stuck at <*>.  I don't understand how is and is' are supposed to be
combined.

This is essentially a writer monad, so it seems that it should just be
concatenation.  I see that algebraically, but not intuitively.

I think I can't do this in a day of mental fog.  Yeah brain is just
not starting up today..


EDIT: Tried again, I just can't juggle it.  It seems the value is
inside the inner monad, and somehow i need to get it out.  Some
knot-tying intuition missing?



Monads do not compose in general.  So it is to be expected that some
trickery goes into the implementation of bind of a monad transformer.

"Each Monad Transformer exists because monads do not compose in general."

http://data.tmorris.net/talks/monad-transformers/8de95b5b9d29c395a68cc8940ca03faad204e474/monad-transformers.pdf


Maybe what I'm trying to do is to create a generic way of composing?


this just has wrappers?
https://github.com/haskell/mtl/blob/master/Control/Monad/Writer/Class.hs

Let's have a look at the WriterT source.
https://hub.darcs.net/ross/transformers
https://hub.darcs.net/ross/transformers/browse/Control/Monad/Trans/Writer/Lazy.hs


So... the implementation is not what I expected: it uses runWriterT
internally.  So indeed: each monad transformer has some kind of trick.

instance (Monoid w, Monad m) => Monad (WriterT w m) where
#if !(MIN_VERSION_base(4,8,0))
    return a = writer (a, mempty)
    {-# INLINE return #-}
#endif
    m >>= k  = WriterT $ do
        ~(a, w)  <- runWriterT m
        ~(b, w') <- runWriterT (k a)
        return (b, w `mappend` w')
    {-# INLINE (>>=) #-}
    fail msg = WriterT $ fail msg
    {-# INLINE fail #-}


And... my definition is wrong!

newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }

The monoid value is inside the monad.




[Reply][About]
[<<][haskell][>>][..]