Hans Höglund | 10 Oct 18:25 2013
Picon

Nested monadic monoids via Traversable?

I have been experimenting with compositions of monads carrying associated monoids (i.e. Writer-style)
and discovered the following pattern:

----------------------------------------------------------------------
{-# LANGUAGE     
    DeriveFunctor,
    DeriveFoldable,
    DeriveTraversable,
    GeneralizedNewtypeDeriving #-}

import Control.Monad
import Control.Monad.Writer hiding ((<>))
import Data.Semigroup
import Data.Foldable (Foldable)
import Data.Traversable (Traversable)
import qualified Data.Traversable as Traversable

newtype Foo m a = Foo (Writer m a)
    deriving (Monad, MonadWriter m, Functor, Foldable, Traversable)

newtype Bar m a = Bar { getBar :: [Foo m a] }
    deriving (Semigroup, Functor, Foldable, Traversable)
instance Monoid m => Monad (Bar m) where
    return = Bar . return . return
    Bar ns >>= f = Bar $ ns >>= joinedSeq . fmap (getBar . f)
        where
            joinedSeq = fmap join . Traversable.sequence

runFoo (Foo x) = runWriter x
runBar (Bar xs) = fmap runFoo xs
(Continue reading)

Hans Höglund | 13 Oct 13:58 2013
Picon

Re: Nested monadic monoids via Traversable?

If anyone is interested, Typeclassopedia pointed me to Composing Monads by Jones and Duponcheel (1993),
which contains exactly my implementation along with some other nice patterns for composing Monads via
Traversable.sequence (called swap in the paper) and related operators. It would be interesting to see
these ideas reimagined with modern type classes.

You can find the paper here:
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.138.4552

Regards,
Hans

On 10 okt 2013, at 18:25, Hans Höglund wrote:

> I have been experimenting with compositions of monads carrying associated monoids (i.e. Writer-style)
and discovered the following pattern:
> 
> ----------------------------------------------------------------------
> {-# LANGUAGE     
>    DeriveFunctor,
>    DeriveFoldable,
>    DeriveTraversable,
>    GeneralizedNewtypeDeriving #-}
> 
> import Control.Monad
> import Control.Monad.Writer hiding ((<>))
> import Data.Semigroup
> import Data.Foldable (Foldable)
> import Data.Traversable (Traversable)
> import qualified Data.Traversable as Traversable
> 
(Continue reading)


Gmane