{-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeOperators #-} {-# OPTIONS_GHC -Wall -Wno-name-shadowing #-} module Data.IMonad ( IMonad (..) -- * Re-exports , module Data.IFunctor ) where import Data.Functor.Sum (Sum (InL, InR)) import Data.IFunctor (IFunctor (imap), type (~~>)) class IFunctor f => IMonad f where ipure :: a ~~> f a ijoin :: f (f a) ~~> f a ijoin = ibind id ibind :: (a ~~> f b) -> (f a ~~> f b) ibind f = ijoin . imap f {-# MINIMAL ipure, (ijoin | ibind) #-} instance IMonad (Sum a) where ipure = InR ijoin (InL x) = InL x ijoin (InR x) = x