RoyalMonad-1000.7: Control/Monad/Royal.hs
-----------------------------------------------------------------------------
-- |
-- Module : Control.Monad.Royal
-- Copyright : (c) Atze van der Ploeg 2015
-- License : BSD-style
-- Maintainer : atzeus@gmail.org
-- Stability : royal
-- Portability : royal
--
-- Introducing his majesty the Royal Monad.
--
-- Royal Monads (or relative polymonads) generalize monads, polymonads _and_ relative monads.
--
-- Therefore Royal Monads (capitalize to emphasise royalness) are the king of monads!
--
-- The ultimate abstraction!
--
-- Ditch your boring old relative, poly or ordinary monad, and start programming with the king of monads!
--
-- Bow before the ultimate generality of the Royal Monad!
{-# LANGUAGE UndecidableInstances,FlexibleInstances,MultiParamTypeClasses #-}
module Control.Monad.Royal where
class RoyalReturn m r where
royalReturn :: r a -> m a
-- |
-- laws (same as monad, but much more Royal):
--
-- prop> royalBind m royalReturn = m
--
-- prop> royalBind (royalReturn x) f = f x
--
-- prop> royalBind m (\x -> royalBind (f x) g) = royalBind (royalBind m f) g
--
class (RoyalReturn m r, RoyalReturn n r, RoyalReturn p r) =>
RoyalMonad m n p r where
royalBind :: m a -> (r a -> n a) -> p a
{- | Relative monads
laws:
prop> relativeBind m royalReturn = m
prop> relativeBind (royalReturn x) f = f x
prop> relativeBind m (\x -> relativeBind (f x) g) = relativeBind (relativeBind m f) g
-}
class RoyalReturn m r => RelMonad m r where
relativeBind :: m a -> (r a -> m b) -> m b
class NonRoyalReturn m where
rreturn :: a -> m a
{- | Relative monads
laws:
prop> polyBind m rreturn = m
prop> polyBind (rreturn x) f = f x
prop> polyBind m (\x -> polyBind (f x) g) = polyBind (polyBind m f) g
-}
class (NonRoyalReturn m, NonRoyalReturn n, NonRoyalReturn p) =>
PolyMonad m n p where
polyBind :: m a -> (a -> n b) -> p b
newtype Id a = Id { fromId :: a}
instance NonRoyalReturn m => RoyalReturn m Id where
royalReturn (Id x) = rreturn x
instance PolyMonad m n p => RoyalMonad m n p Id where
royalBind m f = polyBind m (f . Id)
instance Monad m => NonRoyalReturn m where
rreturn = return
instance Monad m => RoyalMonad m m m Id where
royalBind m f = m >>= (f . Id)