pointless-haskell-0.0.6: src/Generics/Pointless/MonadCombinators.hs
-----------------------------------------------------------------------------
-- |
-- Module : Generics.Pointless.MonadCombinators
-- Copyright : (c) 2009 University of Minho
-- License : BSD3
--
-- Maintainer : hpacheco@di.uminho.pt
-- Stability : experimental
-- Portability : non-portable
--
-- Pointless Haskell:
-- point-free programming with recursion patterns as hylomorphisms
--
-- This module lifts many standard combinators used for point-free programming to combinators over monads.
--
-----------------------------------------------------------------------------
module Generics.Pointless.MonadCombinators where
import Generics.Pointless.Combinators
import Control.Monad
-- | The left-to-right monadic binding combinator.
infixl 1 <<=
(<<=) :: Monad m => (a -> m b) -> m a -> m b
(<<=) f m = m >>= f
-- | Higher-order monadic binding.
bind :: Monad m => (a -> m b,m a) -> m b
bind (f,m) = f <<= m
-- | The monadic left exponentiation combinator.
mlexp :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
mlexp f = curry (bind . (id >< f))
-- | The monadic right exponentiation combinator.
mrexp :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)
mrexp f = curry ((f <<=) . app)
-- | The monadic sum combinator.
infix 5 -||-
(-||-) :: Monad m => (a -> m b) -> (c -> m d) -> (Either a c -> m (Either b d))
(-||-) f g = (return . inl <=< f) \/ (return . inr <=< g)
-- | The strength combinator for strong monads.
-- In Haskell, every monad is a strong monad: <http://comonad.com/reader/2008/deriving-strength-from-laziness/>.
mstrength :: Monad m => (b,m a) -> m (b,a)
mstrength = uncurry (<<=) . (comp . (const return /\ dist) >< id)
where dist = curry id
-- | The monadic fusion combinator.
-- Performs left-to-right distribution of a strong monad over a product.
mfuse :: Monad m => (m a,m b) -> m (a,b)
mfuse = uncurry (<<=) . (curry (mstrength . swap) >< id) . swap
-- | The monadic split combinator.
infix 6 /|\
(/|\) :: Monad m => (a -> m b) -> (a -> m c) -> a -> m (b,c)
(/|\) f g = mfuse . (f /\ g)
-- | The monadic product combinator.
infix 7 >|<
(>|<) :: Monad m => (a -> m c) -> (b -> m d) -> (a,b) -> m (c,d)
f >|< g = f . fst /|\ g . snd