{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wall -Wno-name-shadowing #-}
module Data.IMonad
( IMonad (..)
, 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 = (f a ~~> f a) -> f (f a) ~~> f a
forall k (f :: (k -> *) -> k -> *) (a :: k -> *) (b :: k -> *).
IMonad f =>
(a ~~> f b) -> f a ~~> f b
ibind f a ~~> f a
forall a. a -> a
id
ibind :: (a ~~> f b) -> (f a ~~> f b)
ibind f :: a ~~> f b
f = f (f b) ix -> f b ix
forall k (f :: (k -> *) -> k -> *) (a :: k -> *).
IMonad f =>
f (f a) ~~> f a
ijoin (f (f b) ix -> f b ix)
-> (f a ix -> f (f b) ix) -> f a ix -> f b ix
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a ~~> f b) -> f a ~~> f (f b)
forall k k (f :: (k -> *) -> k -> *) (a :: k -> *) (b :: k -> *).
IFunctor f =>
(a ~~> b) -> f a ~~> f b
imap a ~~> f b
f
{-# MINIMAL ipure, (ijoin | ibind) #-}
instance IMonad (Sum a) where
ipure :: a ix -> Sum a a ix
ipure = a ix -> Sum a a ix
forall k (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR
ijoin :: Sum a (Sum a a) ix -> Sum a a ix
ijoin (InL x :: a ix
x) = a ix -> Sum a a ix
forall k (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL a ix
x
ijoin (InR x :: Sum a a ix
x) = Sum a a ix
x