{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Control.Monad.Trans.Ix
( Ix (..)
, liftIx
, unsafeLiftIx
) where
import Control.Monad (MonadPlus (..))
import Control.Monad.Indexed
import Data.Coerce (coerce)
import Data.Kind (Type)
import qualified Prelude as P
import Prelude hiding (Monad (..), pure)
newtype Ix (m :: Type -> Type) i j a = Ix
{ runIx :: m a
}
deriving (Functor, Applicative, P.Monad)
instance Functor m => IxFunctor (Ix m) where
imap = fmap
instance Applicative m => IxPointed (Ix m) where
ireturn = P.pure
instance Applicative m => IxApplicative (Ix m) where
iap
:: forall i j k a b
. Ix m i j (a -> b)
-> Ix m j k a
-> Ix m i k b
iap = coerce $ (<*>) @m @a @b
instance P.Monad m => IxMonad (Ix m) where
ibind
:: forall i j k a b
. (a -> Ix m j k b)
-> Ix m i j a
-> Ix m i k b
ibind = coerce $ (=<<) @m @a @b
instance MonadPlus m => IxMonadZero (Ix m) where
imzero
:: forall i j a
. Ix m i j a
imzero = coerce $ mzero @m @a
instance MonadPlus m => IxMonadPlus (Ix m) where
implus
:: forall i j a
. Ix m i j a
-> Ix m i j a
-> Ix m i j a
implus = coerce $ mplus @m @a
liftIx :: m a -> Ix m i i a
liftIx = coerce
unsafeLiftIx :: m a -> Ix m i j a
unsafeLiftIx = coerce