[<<][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][>>][..]