effect-monad-0.6: src/Control/Coeffect/Coreader.hs
{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FlexibleInstances, GADTs,
ConstraintKinds, TypeOperators, DataKinds, UndecidableInstances #-}
module Control.Coeffect.Coreader where
import Control.Coeffect
import Data.Type.Set
{-| Provides 'reader monad'-like behaviour but as a comonad, using an indexed
version of the product comonad -}
data IxCoreader s a = IxR { runCoreader :: (a, Set s) }
instance Coeffect IxCoreader where
type Inv IxCoreader s t = (Unionable s t, Split s t (Union s t))
type Unit IxCoreader = '[]
type Plus IxCoreader s t = Union s t
extract (IxR (x, Empty)) = x
extend k (IxR (x, st)) = let (s, t) = split st
in IxR (k (IxR (x, t)), s)
instance CoeffectZip IxCoreader where
type Meet IxCoreader s t = Union s t
type CzipInv IxCoreader s t = (Unionable s t)
czip (IxR (a, s)) (IxR (b, t)) = IxR ((a, b), union s t)
{-| 'ask' for the value of variable 'v', e.g., 'ask (Var::(Var "x"))' -}
ask :: Var v -> IxCoreader '[v :-> a] b -> a
ask _ = \(IxR (_, Ext (Var :-> a) Empty)) -> a