Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to achieve "product of two monads" effect?

Tags:

haskell

monads

Suppose we have two monads, m and m'. Now, suppose we have variables,

-- in real problems, the restriction is some subclass MyMonad, so don't worry
-- if it's the case here that mx and f must essentially be pure.
mx :: Monad m'' => m'' a
f :: Monad m'' => a -> m'' b

Is there a way to create anything similar to the product m x m'? I know this is possible with Arrows, but it seems more complicated (impossible?) for monads, especially when trying to write what mx >>= f should do.

To see this, define

data ProdM a = ProdM (m a) (m' a)
instance Monad ProdM where
    return x = ProdM (return x) (return x)

but now, when we define mx >>= f, it's not clear which value from mx to pass to f,

    (ProdM mx mx') >>= f
        {- result 1 -} = mx >>= f
        {- result 2 -} = mx' >>= f

I want (mx >>= f) :: ProdM to be isomorphic to ((mx >>= f) :: m) x ((mx >>= f) :: m').

like image 203
gatoatigrado Avatar asked Jan 26 '12 02:01

gatoatigrado


People also ask

Do monads compose?

Monads do compose, but the result might not be a monad. In contrast, the composition of two applicatives is necessarily an applicative.

How does a monad work?

What is a Monad? A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.

How are monads pure?

Another way you can say "monads can be pure" is that Haskell distinguishes between creating a monadic computation and running the computation. Creating a monadic computation is pure and doesn't involve any side effects.

What is monadic function?

A monadic function is a function that produces a monadic value. ( Note that we said nothing about its input type) and. Functions of the form f :: a -> m b , where a is the type of the inner value of the monad. ( Call these classic monadic functions)


1 Answers

Yes, this type is a monad. The key is simply to pass both results to f, and only keep the matching field from the result. That is, we keep the first element from the result of passing mx's result, and the second element from the result of passing mx''s result. The instance looks like this:

instance (Monad m, Monad m') => Monad (ProdM m m') where
  return a = ProdM (return a) (return a)
  ProdM mx mx' >>= f = ProdM (mx >>= fstProd . f) (mx' >>= sndProd . f)
    where fstProd (ProdM my _) = my
          sndProd (ProdM _ my') = my'

ProdM is available in the monad-products package under the name Product.

like image 177
ehird Avatar answered Sep 27 '22 00:09

ehird