packages feed

she-0.0: examples/IFunctor.lhs

> {-# OPTIONS_GHC -F -pgmF she #-}
> {-# LANGUAGE KindSignatures, RankNTypes, TypeOperators, GADTs #-}

> module IFunctor where

> type s :-> t = forall i. s i -> t i

> class IFunctor (phi :: ({i} -> *) -> {o} -> *) where
>   imap :: (s :-> t) -> phi s :-> phi t

> class IFunctor phi => IMonad (phi :: ({i} -> *) -> {i} -> *) where
>   iskip :: s :-> phi s
>   iextend :: (s :-> phi t) -> (phi s :-> phi t)

> iseq :: IMonad phi => (r :-> phi s) -> (s :-> phi t) -> (r :-> phi t)
> iseq f g = iextend g . f

> (>>-) :: IMonad phi => phi s i -> (s :-> phi t) -> phi t i
> (>>-) = flip iextend

> data (:*) :: (({i} -> *) -> {i} -> *) -> ({i} -> *) -> {i} -> * where
>   Ret  :: q i -> (phi :* q) i
>   Do   :: phi (phi :* q) i -> (phi :* q) i

> instance IFunctor phi => IFunctor ((:*) phi) where
>   imap f = iextend (iskip . f)

> instance IFunctor phi => IMonad ((:*) phi) where
>   iskip = Ret
>   iextend f (Ret x) = f x
>   iextend f (Do d) = Do (imap (iextend f) d)

Some predicates we like.

> data (:-) :: * -> {x} -> {x} -> * where
>   V :: a -> (a :- x) x

> ret :: IMonad phi => a -> phi (a :- i) i
> ret a = iskip (V a)

> knownState :: (a -> t i) -> (a :- i) :-> t
> knownState f (V a) = f a

> (?-) :: IMonad phi => phi (a :- j) i -> (a -> phi t j) -> phi t i
> c ?- f = c >>- knownState f