Ideal Monads and coproduct of them.
Type class to represent ideal monads in terms of the "ideal part" of ideal monads. See README for more.
monad-ideals: Ideal Monads and coproduct of Monads
Revives Control.Monad.Ideal from old versions of category-extras.
Ideal Monads
Ideal monads[^1] are certain kind of monads. Informally, an ideal monad M is a Monad which can be written as a disjoint union of "pure" values and "impure" values, and its join operation on "impure" values never produces "pure" values.
[^1]: N. Ghani and T. Uustalu, “Coproducts of ideal monads,” Theoret. Inform. and Appl., vol. 38, pp. 321–342, 2004.
data M a = Pure a | Impure (...)
pure :: a -> M a
pure = Pure
join :: M (M a) -> M a
join (Pure ma) = ma
join (Impure ...) = Impure (...)
-- Impure values of @M a@ never becomes pure again
Formally, an ideal monad m is a Monad equipped with
Functor m₀, called the ideal part ofm- Natural isomorphism
iso :: ∀a. Either a (m₀ a) -> m a(and its inverseiso⁻¹ :: ∀a. m a -> Either a (m₀ a)) - Natural transformation
idealize :: ∀a. m₀ (m a) -> m₀ a
satisfying these two properties.
iso . Left === pure :: ∀a. a -> m aeither id (iso . Right . idealize) . iso⁻¹ === join :: m (m a) -> m a
This package provides MonadIdeal, a type class to represent ideal monads in terms of its ideal part m₀ (instead of a subclass of Monad to represent ideal monad itself.)
class (Isolated m0, Bind m0) => MonadIdeal m0 where
idealBind :: m0 a -> (a -> Ideal m0 b) -> m0 b
type Ideal m0 a
-- | Constructor of @Ideal@
ideal :: Either a (m0 a) -> Ideal m0 a
-- | Deconstructor of @Ideal@
runIdeal :: Ideal m0 a -> Either a (m0 a)
Here, Ideal m0 corresponds to the ideal monad which would have m0 as its ideal part.
Isolated class
There is a generalization to ideal monads, which are almost ideal monads, but lack a condition that says "an impure value does not become a pure value by the join operation".
A monad m in this class has natural isomorphism Either a (m₀ a) -> m a with some functor m₀, and pure is the part of m which is not m₀. Formally, the defining data of this class are:
Functor m₀, called the impure part ofm- Natural isomorphism
iso :: ∀a. Either a (m₀ a) -> m a(and its inverseiso⁻¹ :: ∀a. m a -> Either a (m₀ a)) iso . Left === pure :: ∀a. a -> m a
Combined with the monad laws of m, join :: ∀a. m (m a) -> m a must be equal to the following natural transformation with some impureJoin.
join :: ∀a. m (m a) -> m a
join mma = case iso⁻¹ mma of
Left ma -> ma
Right m₀ma -> impureJoin m₀ma
where
impureJoin :: ∀a. m₀ (m a) -> m a
The Isolated class is a type class for a functor which can be thought of as an impure part of some monad.
newtype Unite f a = Unite { runUnite :: Either a (f a) }
class Functor m0 => Isolated m0 where
impureBind :: m0 a -> (a -> Unite m0 b) -> Unite m0 b
Coproduct of monads
Coproduct m ⊕ n of two monads[^2] m, n is the coproduct (category-theoretic sum) in the category of monad and monad morphisms. [^3]
In basic terms, m ⊕ n is a monad with the following functions and properties.
Monad morphism
inject1 :: ∀a. m a -> (m ⊕ n) aMonad morphism
inject2 :: ∀a. n a -> (m ⊕ n) aFunction
eitherMonadwhich takes two monad morphisms and return a monad morphism.eitherMonad :: (∀a. m a -> t a) -> (∀a. n a -> t a) -> (∀a. (m ⊕ n) a -> t a)Given arbitrary monads
m, n, t,For all monad morphisms
f1andf2,eitherMonad f1 f2 . inject1 = f1eitherMonad f1 f2 . inject2 = f2
For any monad morphism
f :: ∀a. (m ⊕ n) a -> t a,fequals toeitherMonad f1 f2for some uniquef1, f2. Or, equvalently,f = eitherMonad (f . inject1) (f . inject2).
Coproduct of two monads does not always exist, but for ideal monads or monads with Isolated impure parts, their coproducts exist. This package provides a type constructor (:+) below.
-- Control.Monad.Coproduct
data (:+) (m :: Type -> Type) (n :: Type -> Type) (a :: Type)
Using this type constructor, coproduct of monad can be constructed in two ways.
If
m0, n0areIsolatedi.e. the impure part of monadsUnite m0, Unite n0respectively,m0 :+ n0is alsoIsolatedandUnite (m0 :+ n0)is the coproduct of monadsUnite m0 ⊕ Unite n0.If
m0, n0areMonadIdeali.e. the ideal part of ideal monadsIdeal m0, Ideal n0respectively,m0 :+ n0is alsoMonadIdealandIdeal (m0 :+ n0)is the coproduct of monadsIdeal m0 ⊕ Ideal n0.
[^2]: Jiří Adámek, Nathan Bowler, Paul B. Levy and Stefan Milius, "Coproducts of Monads on Set." (https://doi.org/10.48550/arXiv.1409.3804)
[^3]: To name the same concept to monad morphism, the term "monad transformation" is used in transformers package (Control.Monad.Trans.Class.)
Duals
This package also provides the duals of ideal monads and coproducts of them: Coideal comonads and products of them.