MHask 0.1.0.0 → 0.2.0.0
raw patch · 13 files changed
+227/−126 lines, 13 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
- MHask.Util: (~>) :: (Monad a, Monad b, Monad c) => (a ~> b) -> (b ~> c) -> (a ~> c)
+ MHask.Util: (~<~) :: (Monad a, Monad b, Monad c) => (c <~ b) -> (b <~ a) -> (c <~ a)
+ MHask.Util: (~>~) :: (Monad a, Monad b, Monad c) => (a ~> b) -> (b ~> c) -> (a ~> c)
- MHask.Comonad: class Copointed t => Comonad t where extend f = duplicate ~> fmap f duplicate = extend id
+ MHask.Comonad: class Copointed t => Comonad t where duplicate = extend id extend f = fmap f ~<~ duplicate
- MHask.Comonad: duplicate :: (Comonad t, Monad m, Monad (t m), Monad (t (t m))) => t m ~> t (t m)
+ MHask.Comonad: duplicate :: (Comonad t, Monad m) => t (t m) <~ t m
- MHask.Comonad: extend :: (Comonad t, Monad m, Monad n, Monad (t m), Monad (t n)) => (t m ~> n) -> (t m ~> t n)
+ MHask.Comonad: extend :: (Comonad t, Monad m, Monad n) => (m <~ t n) -> (t m <~ t n)
- MHask.Copointed: extract :: (Copointed t, Monad m, Monad (t m)) => t m ~> m
+ MHask.Copointed: extract :: (Copointed t, Monad m) => m <~ t m
- MHask.Functor: fmap :: (Functor t, Monad m, Monad n, Monad (t m), Monad (t n)) => (m ~> n) -> (t m ~> t n)
+ MHask.Functor: fmap :: (Functor t, Monad m, Monad n) => (m ~> n) -> (t m ~> t n)
- MHask.Indexed.Comonad: class IxCopointed t => IxComonad t where iextend f = iduplicate ~> imap f iduplicate = iextend id
+ MHask.Indexed.Comonad: class IxCopointed t => IxComonad t where iduplicate = iextend id iextend f = imap f ~<~ iduplicate
- MHask.Indexed.Comonad: iduplicate :: (IxComonad t, Monad m, Monad (t i k m), Monad (t i j (t j k m))) => t i k m ~> t i j (t j k m)
+ MHask.Indexed.Comonad: iduplicate :: (IxComonad t, Monad m) => t i j (t j k m) <~ t i k m
- MHask.Indexed.Comonad: iextend :: (IxComonad t, Monad m, Monad n, Monad (t i j m), Monad (t j k n), Monad (t i k m)) => (t j k m ~> n) -> (t i k m ~> t i j n)
+ MHask.Indexed.Comonad: iextend :: (IxComonad t, Monad m, Monad n) => (m <~ t j k n) -> (t i j m <~ t i k n)
- MHask.Indexed.Copointed: iextract :: (IxCopointed t, Monad m, Monad (t i i m)) => t i i m ~> m
+ MHask.Indexed.Copointed: iextract :: (IxCopointed t, Monad m) => m <~ t i i m
- MHask.Indexed.Functor: imap :: (IxFunctor t, Monad m, Monad n, Monad (t i j m), Monad (t i j n)) => (m ~> n) -> (t i j m ~> t i j n)
+ MHask.Indexed.Functor: imap :: (IxFunctor t, Monad m, Monad n) => (m ~> n) -> (t i j m ~> t i j n)
- MHask.Indexed.Monad: class IxPointed t => IxMonad t where ijoin = ibind id ibind f = imap f ~> ijoin
+ MHask.Indexed.Monad: class IxPointed t => IxMonad t where ijoin = ibind id ibind f = imap f ~>~ ijoin
- MHask.Indexed.Monad: ibind :: (IxMonad t, Monad m, Monad (t i j m), Monad n, Monad (t j k n)) => (m ~> t j k n) -> (t i j m ~> t i k n)
+ MHask.Indexed.Monad: ibind :: (IxMonad t, Monad m, Monad n) => (m ~> t j k n) -> (t i j m ~> t i k n)
- MHask.Indexed.Monad: ijoin :: (IxMonad t, Monad m, Monad (t i j (t j k m)), Monad (t i k m)) => t i j (t j k m) ~> t i k m
+ MHask.Indexed.Monad: ijoin :: (IxMonad t, Monad m) => t i j (t j k m) ~> t i k m
- MHask.Indexed.Pointed: ireturn :: (IxPointed t, Monad m, Monad (t i i m)) => m ~> t i i m
+ MHask.Indexed.Pointed: ireturn :: (IxPointed t, Monad m) => m ~> t i i m
- MHask.Monad: bind :: (Monad t, Monad m, Monad (t m), Monad n, Monad (t n)) => (m ~> t n) -> (t m ~> t n)
+ MHask.Monad: bind :: (Monad t, Monad m, Monad n) => (m ~> t n) -> (t m ~> t n)
- MHask.Monad: class Pointed t => Monad t where join = bind id bind f = fmap f ~> join
+ MHask.Monad: class Pointed t => Monad t where join = bind id bind f = fmap f ~>~ join
- MHask.Monad: join :: (Monad t, Monad m, Monad (t m), Monad (t (t m))) => t (t m) ~> t m
+ MHask.Monad: join :: (Monad t, Monad m) => t (t m) ~> t m
- MHask.Pointed: return :: (Pointed t, Monad m, Monad (t m)) => (m ~> t m)
+ MHask.Pointed: return :: (Pointed t, Monad m) => m ~> t m
- MHask.Util: type (~>) m n = forall x. m x -> n x
+ MHask.Util: type (<~) m n = n ~> m
Files
- MHask.cabal +30/−18
- MHask.hs +35/−12
- MHask/Comonad.hs +18/−14
- MHask/Copointed.hs +12/−9
- MHask/Functor.hs +9/−2
- MHask/Indexed/Comonad.hs +18/−20
- MHask/Indexed/Copointed.hs +14/−8
- MHask/Indexed/Functor.hs +10/−4
- MHask/Indexed/Monad.hs +14/−14
- MHask/Indexed/Pointed.hs +12/−6
- MHask/Monad.hs +11/−10
- MHask/Pointed.hs +7/−7
- MHask/Util.hs +37/−2
MHask.cabal view
@@ -1,36 +1,48 @@--- Initial MHask.cabal generated by cabal init. For further documentation,--- see http://haskell.org/cabal/users-guide/- name: MHask-version: 0.1.0.0+version: 0.2.0.0 synopsis: The category of monads-category: Control description: MHask is the category where .- * The objects are Haskell types of kind (* -> *) that have an instance of Monad- * An arrow from object m to object n is a Haskell function of the form (forall x. m x -> n x)+ * The objects are Haskell types of kind @(* → *)@ that have an instance of `Prelude.Monad'+ .+ * An arrow from object m to object n is a Haskell function of the form @(forall x. m x → n x)@+ . * Arrow composition is merely a specialization of Haskell function composition- * The identity arrow for the object m is the id function in Haskell, specialized to (forall x. m x -> m x) .- Functor should actually be called Endofunctor, because if m is an object in MHask,- then an instance t of Functor can transform object m into object (t m).- You will see *a lot* of constraints in the type classes defined herein.- Though daunting at first, you will soon realize that they are *all* Prelude.Monad constraints,- and their interpretation is simply a guarantee that- "the objects of MHask are types of kind (* -> *) that have an instance of Monad."+ * The identity arrow for the object m is the `Prelude.id' function in Haskell,+ specialized to @(forall x. m x → m x)@+ .+ It is assumed that any instances of the classes provided here also have an instance+ for Monad of the form @instance (Monad m) ⇒ Monad (t m)@, thus guaranteeing that @(t m)@+ (or @(t i j m)@ for the indexed types) is always a Monad. If it were valid Haskell, I'd write:+ .+ > class (forall m. Monad m ⇒ Monad (t m)) ⇒ Functor t+ .+ 'MHask.Functor.Functor' should actually be called Endofunctor, because if m is an object in MHask,+ then an instance t of `Functor' can map object m to object (t m), and arrows from + m to n get mapped to arrows from (t m) to (t n). + homepage: https://github.com/DanBurton/MHask#readme license: BSD3 license-file: LICENSE author: Dan Burton maintainer: danburton.email@gmail.com--- copyright: --- category: +category: Control build-type: Simple cabal-version: >=1.8 +source-repository head+ type: git+ location: git://github.com/DanBurton/MHask.git++source-repository this+ type: git+ location: git://github.com/DanBurton/MHask.git+ tag: MHask-0.2.0.0+ library exposed-modules: MHask, MHask.Comonad, MHask.Monad, MHask.Copointed, MHask.Pointed, MHask.Util, MHask.Functor, MHask.Indexed.Comonad, MHask.Indexed.Monad, MHask.Indexed.Copointed, MHask.Indexed.Pointed, MHask.Indexed.Functor- -- other-modules: - build-depends: base == 4.6.*, transformers >= 0.3++ build-depends: base >= 2 && < 4.7, transformers >= 0.3
MHask.hs view
@@ -1,16 +1,39 @@ -module MHask (module MHask) where+-- | Various abstractions in the category of MHask.+-- This re-exports everything, and should be imported+-- qualified so that the operations and classes+-- do not clash with their Hask counterparts.+-- +-- > import qualified MHask+module MHask (+ -- * Prelimiaries+ module MHask.Util, -import MHask.Util as MHask+ -- * Classes+ module MHask.Functor,+ module MHask.Pointed,+ module MHask.Monad,+ module MHask.Copointed,+ module MHask.Comonad, -import qualified MHask.Functor as MHask-import qualified MHask.Pointed as MHask-import qualified MHask.Monad as MHask-import qualified MHask.Copointed as MHask-import qualified MHask.Comonad as MHask+ -- * Indexed Classes+ module MHask.Indexed.Functor,+ module MHask.Indexed.Pointed,+ module MHask.Indexed.Monad,+ module MHask.Indexed.Copointed,+ module MHask.Indexed.Comonad,+ ) where -import qualified MHask.Indexed.Functor as MHask-import qualified MHask.Indexed.Pointed as MHask-import qualified MHask.Indexed.Monad as MHask-import qualified MHask.Indexed.Copointed as MHask-import qualified MHask.Indexed.Comonad as MHask+import MHask.Util++import MHask.Functor+import MHask.Pointed+import MHask.Monad+import MHask.Copointed+import MHask.Comonad++import MHask.Indexed.Functor+import MHask.Indexed.Pointed+import MHask.Indexed.Monad+import MHask.Indexed.Copointed+import MHask.Indexed.Comonad
MHask/Comonad.hs view
@@ -2,27 +2,31 @@ {-# LANGUAGE Rank2Types #-} {-# LANGUAGE DefaultSignatures #-} --- Compare to comonad.Control.Comonad (Comonad)+-- | Compare to comonad.Control.Comonad (Comonad) module MHask.Comonad where -import MHask.Util -import Control.Monad.Trans.State-import Control.Monad.Trans.Reader-import Control.Monad.Trans.Writer +import MHask.Util+ import qualified MHask.Functor as MHask import qualified MHask.Copointed as MHask +-- | Dual of "MHask.Monad" class (MHask.Copointed t) => Comonad t where- extend :: (Monad m, Monad n, Monad (t m), Monad (t n))- => (t m ~> n) -> (t m ~> t n)- default extend :: (Monad m, Monad n, Monad (t m), Monad (t n),- Monad (t (t m)))- => (t m ~> n) -> (t m ~> t n)- extend f = duplicate ~> MHask.fmap f-- duplicate :: (Monad m, Monad (t m), Monad (t (t m)))- => t m ~> t (t m)+ duplicate :: (Monad m)+ => t (t m) <~ t m+ default duplicate :: (Monad m, Monad (t m))+ => t (t m) <~ t m duplicate = extend id++ extend :: (Monad m, Monad n)+ => (m <~ t n) -> (t m <~ t n)+ default extend ::+ (Monad m, Monad n,+ Monad (t m), Monad (t n),+ Monad (t (t n)))+ => (m <~ t n) -> (t m <~ t n)+ extend f = MHask.fmap f ~<~ duplicate+
MHask/Copointed.hs view
@@ -2,31 +2,34 @@ {-# LANGUAGE Rank2Types #-} --- Compare to todo.Copointed+-- | Compare to comonad.Control.Comonad (Copointed) module MHask.Copointed where + import MHask.Util +import Data.Monoid+import Control.Monad (liftM) import Control.Monad.Trans.State import Control.Monad.Trans.Reader import Control.Monad.Trans.Writer -import Data.Monoid-import Control.Monad (liftM)- import qualified MHask.Functor as MHask ++-- | The dual of "MHask.Pointed" class (MHask.Functor t) => Copointed t where- extract :: (Monad m, Monad (t m))- => t m ~> m+ extract :: (Monad m)+ => m <~ t m -instance Copointed (WriterT w) where- extract = liftM fst . runWriterT- instance (Monoid s) => Copointed (StateT s) where extract = flip evalStateT mempty instance (Monoid r) => Copointed (ReaderT r) where extract = flip runReaderT mempty++instance Copointed (WriterT w) where+ extract = liftM fst . runWriterT+
MHask/Functor.hs view
@@ -1,7 +1,8 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE Rank2Types #-} --- Compare to base.Prelude.Functor (Functor)++-- | Compare to base.Prelude.Functor (Functor) module MHask.Functor where import Prelude hiding (Functor, fmap)@@ -12,8 +13,14 @@ import Control.Monad.Trans.Writer ++-- | Functor is its own dual. class Functor t where- fmap :: (Monad m, Monad n, Monad (t m), Monad (t n))+ -- | Flipping the arrows on fmap's type signature+ -- is just the same type signature in disguise.+ -- + -- > (m <~ n) -> (t m <~ t n)+ fmap :: (Monad m, Monad n) => (m ~> n) -> (t m ~> t n)
MHask/Indexed/Comonad.hs view
@@ -2,33 +2,31 @@ {-# LANGUAGE Rank2Types #-} {-# LANGUAGE DefaultSignatures #-} --- Compare to indexed.Control.Comonad.Indexed (IxComonad)+-- | Compare to indexed.Control.Comonad.Indexed (IxComonad) module MHask.Indexed.Comonad where -import MHask.Util -import Control.Monad.Trans.State-import Control.Monad.Trans.Reader-import Control.Monad.Trans.Writer +import MHask.Util+ import qualified MHask.Indexed.Functor as MHask import qualified MHask.Indexed.Copointed as MHask -+-- | Indexed version of "MHask.Comonad".+-- Dual of "MHask.Indexed.Monad" class (MHask.IxCopointed t) => IxComonad t where- iextend :: (Monad m, Monad n,- Monad (t i j m), Monad (t j k n), Monad (t i k m))- => (t j k m ~> n) -> (t i k m ~> t i j n)- default iextend :: (Monad m, Monad n,- Monad (t i j m), Monad (t j k n), Monad (t i k m),- Monad (t i j (t j k m)), Monad (t j k m), Monad (t i j n))- => (t j k m ~> n) -> (t i k m ~> t i j n)- iextend f = iduplicate ~> MHask.imap f+ iduplicate :: (Monad m)+ => t i j (t j k m) <~ t i k m+ default iduplicate :: (Monad m, Monad (t j k m))+ => t i j (t j k m) <~ t i k m+ iduplicate = iextend id - iduplicate :: (Monad m, Monad (t i k m), Monad (t i j (t j k m)))- => t i k m ~> t i j (t j k m)+ iextend :: (Monad m, Monad n)+ => (m <~ t j k n) -> (t i j m <~ t i k n)+ default iextend ::+ (Monad m, Monad n,+ Monad (t i j m), Monad (t j k n), Monad (t i k n),+ Monad (t i j (t j k n)))+ => (m <~ t j k n) -> (t i j m <~ t i k n)+ iextend f = MHask.imap f ~<~ iduplicate - default iduplicate :: (Monad m, Monad (t i k m), Monad (t i j (t j k m)),- (Monad (t j k (t j k m))), (Monad (t i j m)), (Monad (t j k m)))- => t i k m ~> t i j (t j k m)- iduplicate = iextend id
MHask/Indexed/Copointed.hs view
@@ -2,21 +2,27 @@ {-# LANGUAGE Rank2Types #-} {-# LANGUAGE DefaultSignatures #-} --- Compare to indexed.Data.Functor.Indexed (IxCopointed)+-- | Compare to indexed.Data.Functor.Indexed (IxCopointed) module MHask.Indexed.Copointed where + import MHask.Util -import Control.Monad.Trans.State-import Control.Monad.Trans.Reader-import Control.Monad.Trans.Writer +++++ import qualified MHask.Copointed as MHask import qualified MHask.Indexed.Functor as MHask +-- | The indexed version of "MHask.Copointed".+-- The dual of "MHask.Indexed.Pointed". class (MHask.IxFunctor t) => IxCopointed t where- iextract :: (Monad m, Monad (t i i m))- => t i i m ~> m- default iextract :: (Monad m, Monad (t i i m), MHask.Copointed (t i i))- => t i i m ~> m+ iextract :: (Monad m)+ => m <~ t i i m+ default iextract :: (Monad m,+ MHask.Copointed (t i i))+ => m <~ t i i m iextract = MHask.extract
MHask/Indexed/Functor.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE Rank2Types #-} {-# LANGUAGE DefaultSignatures #-} --- Compare to indexed.Data.Functor.Indexed (IxFunctor)+-- | Compare to indexed.Data.Functor.Indexed (IxFunctor) module MHask.Indexed.Functor where import MHask.Util@@ -13,10 +13,16 @@ import qualified MHask.Functor as MHask +-- | The indexed version of "MHask.Functor".+-- IxFunctor is its own dual. class IxFunctor t where- imap :: (Monad m, Monad n, Monad (t i j m), Monad (t i j n))+ -- | Flipping the arrows on imap's type signature+ -- is just the same type signature in disguise.+ -- + -- > (m <~ n) -> (t i j m <~ t i j n)+ imap :: (Monad m, Monad n) => (m ~> n) -> (t i j m ~> t i j n)- default imap :: (Monad m, Monad n, Monad (t i j m), Monad (t i j n),- MHask.Functor (t i j))+ default imap :: (Monad m, Monad n,+ MHask.Functor (t i j)) => (m ~> n) -> (t i j m ~> t i j n) imap = MHask.fmap
MHask/Indexed/Monad.hs view
@@ -2,31 +2,31 @@ {-# LANGUAGE Rank2Types #-} {-# LANGUAGE DefaultSignatures #-} --- Compare to indexed.Control.Monad.Indexed (IxMonad)+-- | Compare to indexed.Control.Monad.Indexed (IxMonad) module MHask.Indexed.Monad where -import MHask.Util -import Control.Monad.Trans.State-import Control.Monad.Trans.Reader-import Control.Monad.Trans.Writer -import qualified MHask.Monad as MHask+import MHask.Util+ import qualified MHask.Indexed.Pointed as MHask import qualified MHask.Indexed.Functor as MHask +-- | Indexed version of "MHask.Monad".+-- Dual of "MHask.Indexed.Comonad" class (MHask.IxPointed t) => IxMonad t where- ijoin :: (Monad m, Monad (t i j (t j k m)), Monad (t i k m))+ ijoin :: (Monad m) => t i j (t j k m) ~> t i k m- default ijoin :: (Monad m, Monad (t i j (t j k m)), Monad (t i k m),- Monad (t j k m))+ default ijoin :: (Monad m, Monad (t j k m)) => t i j (t j k m) ~> t i k m ijoin = ibind id -- ibind :: (Monad m, Monad (t i j m), Monad n, Monad (t j k n))+ ibind :: (Monad m, Monad n) => (m ~> t j k n) -> (t i j m ~> t i k n)- default ibind :: (Monad m, Monad (t i j m), Monad n, Monad (t j k n),- Monad (t i k n), Monad (t i j (t j k n)))+ default ibind ::+ (Monad m, Monad n,+ Monad (t i j m), Monad (t j k n), Monad (t i k n),+ Monad (t i j (t j k n))) => (m ~> t j k n) -> (t i j m ~> t i k n)- ibind f = MHask.imap f ~> ijoin+ ibind f = MHask.imap f ~>~ ijoin+
MHask/Indexed/Pointed.hs view
@@ -2,21 +2,27 @@ {-# LANGUAGE Rank2Types #-} {-# LANGUAGE DefaultSignatures #-} --- Compare to indexed.Data.Functor.Indexed (IxPointed)+-- | Compare to indexed.Data.Functor.Indexed (IxPointed) module MHask.Indexed.Pointed where + import MHask.Util -import Control.Monad.Trans.State-import Control.Monad.Trans.Reader-import Control.Monad.Trans.Writer +++++ import qualified MHask.Pointed as MHask import qualified MHask.Indexed.Functor as MHask +-- | The indexed version of "MHask.Pointed".+-- The dual of "MHask.Indexed.Copointed". class (MHask.IxFunctor t) => IxPointed t where- ireturn :: (Monad m, Monad (t i i m))+ ireturn :: (Monad m) => m ~> t i i m- default ireturn :: (Monad m, Monad (t i i m), MHask.Pointed (t i i))+ default ireturn :: (Monad m,+ MHask.Pointed (t i i)) => m ~> t i i m ireturn = MHask.return
MHask/Monad.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE Rank2Types #-} {-# LANGUAGE DefaultSignatures #-} --- Compare to base.Prelude.Monad+-- | Compare to base.Prelude (Monad) module MHask.Monad where import Prelude hiding (Monad, join)@@ -12,19 +12,20 @@ import qualified MHask.Functor as MHask import qualified MHask.Pointed as MHask -import Control.Monad.Trans.State-import Control.Monad.Trans.Reader-import Control.Monad.Trans.Writer -+-- | Dual of "MHask.Comonad" class (MHask.Pointed t) => Monad t where- join :: (P.Monad m, P.Monad (t m), P.Monad (t (t m)))+ join :: (P.Monad m) => t (t m) ~> t m+ default join :: (P.Monad m, P.Monad (t m))+ => t (t m) ~> t m join = bind id - bind :: (P.Monad m, P.Monad (t m), P.Monad n, P.Monad (t n))+ bind :: (P.Monad m, P.Monad n) => (m ~> t n) -> (t m ~> t n)- default bind :: (P.Monad m, P.Monad (t m), P.Monad n, P.Monad (t n),- P.Monad (t (t n)))+ default bind ::+ (P.Monad m, P.Monad n,+ P.Monad (t m), P.Monad (t n),+ P.Monad (t (t n))) => (m ~> t n) -> (t m ~> t n)- bind f = MHask.fmap f ~> join+ bind f = MHask.fmap f ~>~ join
MHask/Pointed.hs view
@@ -1,7 +1,8 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE Rank2Types #-} --- no relevant comparison++-- | Equivalent to transformers.Control.Monad.Trans.Class (MonadTrans) module MHask.Pointed where import Prelude hiding (return)@@ -12,17 +13,16 @@ import Control.Monad.Trans.State import Control.Monad.Trans.Reader import Control.Monad.Trans.Writer-import Control.Monad.Trans.Class import qualified MHask.Functor as MHask -class (MHask.Functor t) => Pointed t where- return :: (Monad m, Monad (t m))- => (m ~> t m) --- This is basically MonadTrans--- lift = MHask.return+-- | The dual of "MHask.Copointed"+class (MHask.Functor t) => Pointed t where+ return :: (Monad m)+ => m ~> t m+ instance Pointed (StateT s) where return mx = StateT $ \s -> liftM (\x -> (x, s)) mx
MHask/Util.hs view
@@ -1,9 +1,44 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE Rank2Types #-} +-- | This module sets the stage for the rest of the package.+-- It defines a type synonym @~>@ which cleans up the+-- type signatures,+-- and @~>~@ which is used in the default implementation+-- of bind. These represent the type of arrows and arrow composition+-- in MHask, respectively.+-- +-- By using @~>@, type signatures for the MHask class operations+-- can be easily compared to their Hask counterparts. However,+-- as a reminder that you are dealing with Monads, where+-- typically you would see @a@ and @b@ in the Hask counterpart,+-- you will instead see @m@ and @n@, and where you would+-- typically see @m@ or @w@, you will instead see @t@,+-- as a mnemonic for Monad transformer.+-- +-- For illustrative purposes, this module also provides+-- @<~@ and @~<~@, to clearly illustrate how duals are+-- nothing more than just \"flipping the arrows\".+-- You are encouraged to compare docs or even source files+-- to see just how similar they are, all the way down+-- to default implementations. module MHask.Util where +-- | The @~>@ type represents arrows in the+-- category of MHask. type m ~> n = forall x. m x -> n x -(~>) :: (Monad a, Monad b, Monad c) => (a ~> b) -> (b ~> c) -> (a ~> c)-f1 ~> f2 = f2 . f1+-- | It's just @~>@ flipped.+-- +-- > type m <~ n = n ~> m+type m <~ n = n ~> m++-- | Left-to-right composition of arrows in MHask.+(~>~) :: (Monad a, Monad b, Monad c) => (a ~> b) -> (b ~> c) -> (a ~> c)+f1 ~>~ f2 = f2 . f1++-- | It's just @~>~@ flipped.+-- +-- > (~<~) = flip (~>~)+(~<~) :: (Monad a, Monad b, Monad c) => (c <~ b) -> (b <~ a) -> (c <~ a)+(~<~) = flip (~>~)