# Effects

(*>) : EffM m a xs (\v => xs) -> EffM m b xs (\v7 => xs) -> EffM m b xs (\v8 => xs)
  Fixity
    Left associative, precedence 3
(:::) : lbl -> EFFECT -> EFFECT
  Fixity
    Non-associative, precedence 5
(<$>) : (a -> b) -> EffM m a xs (\v => xs) -> EffM m b xs (\v8 => xs)
  Fixity
    Left associative, precedence 4
(<*>) : EffM m (a -> b) xs (\v => xs) -> EffM m a xs (\v8 => xs) -> EffM m b xs (\v9 => xs)
  Fixity
    Left associative, precedence 3
(>>=) : EffM m a xs xs' -> ((val : a) -> EffM m b (xs' val) xs'') -> EffM m b xs xs''
  Fixity
    Left associative, precedence 1
data EFFECT : Type

  The `EFFECT` Data type describes how to promote the Effect
  description into a concrete effect.

  MkEff : Type -> Effect -> EFFECT
data EffM : (m : Type -> Type) -> (x : Type) -> (es : List EFFECT) -> (ce : x -> List EFFECT) -> Type

  Definition of a language of effectful programs.

  x

    The return type of the result.

  es

    The list of allowed side-effects.

  ce

    Function to compute a new list of allowed side-effects.

  Value : (val : a) -> EffM m a (xs val) xs
  EBind : EffM m a xs xs' -> ((val : a) -> EffM m b (xs' val) xs'') -> EffM m b xs xs''
  CallP : (prf : Elem (MkEff a e) xs) -> (eff : e t a b) -> EffM m t xs (\v => updateResTy v xs prf eff)
  LiftP : (prf : SubList ys xs) -> EffM m t ys ys' -> EffM m t xs (\v => updateWith (ys' v) xs prf)
  New : Handler e' m => (e : EFFECT) -> resTy -> {auto prf : e = MkEff resTy e'} -> EffM m t (e :: es) (\v => e :: es) -> EffM m t es (\v11 => es)
  (:-) : (l : ty) -> EffM m t [x] xs' -> EffM m t [l ::: x] (\v => map (\ARG => l ::: ARG) (xs' v))
    Fixity
      Non-associative, precedence 5
Effect : Type

  The Effect type describes effectful computations.

  This type is parameterised by:

  - The return type of the computation.
  - The input resource.
  - The computation to run on the resource given the return value.
interface Handler

  Handler interfaces describe how an effect `e` is translated to the
  underlying computation context `m` for execution.

  handle : Handler e m => (r : res) -> (eff : e t res resk) -> (k : (x : t) -> resk x -> m a) -> m a

    How to handle the effect.

data LRes : lbl -> Type -> Type
  (:=) : (x : lbl) -> res -> LRes x res
    Fixity
      Non-associative, precedence 5
data SubElem : a -> List a -> Type
  Z : SubElem a (a :: as)
  S : SubElem a as -> SubElem a (b :: as)
data SubList : List a -> List a -> Type
  SubNil : SubList [] xs
  InList : SubElem x ys -> SubList xs ys -> SubList (x :: xs) ys
call : (eff : e t a b) -> {auto prf : Elem (MkEff a e) xs} -> EffM m t xs (\v => updateResTy v xs prf eff)
dropEnv : Env m ys -> SubList xs ys -> Env m xs

  make an environment corresponding to a sub-list

dropFirst : SubList xs ys -> SubList xs (x :: ys)
dropPrefix : SubList xs ys -> SubList xs (zs ++ ys)
dropSuffix : SubList xs ys -> SubList xs (ys ++ zs)
eff : Env m xs -> EffM m a xs xs' -> ((x : a) -> Env m (xs' x) -> m b) -> m b
envElem : SubElem x xs -> Env m xs -> Env m [x]
inPrefix : SubElem x ys -> SubList xs ys -> SubElem x (ys ++ zs)
inSuffix : SubElem x ys -> SubList xs ys -> SubElem x (zs ++ ys)
lift : EffM m t ys ys' -> {auto prf : SubList ys xs} -> EffM m t xs (\v => updateWith (ys' v) xs prf)
mapE : (a -> EffM m b xs (\underscore => xs)) -> List a -> EffM m (List b) xs (\underscore => xs)
mapVE : (a -> EffM m b xs (\underscore => xs)) -> Vect n a -> EffM m (Vect n b) xs (\underscore => xs)
new : Handler e' m => (e : EFFECT) -> resTy -> {auto prf : e = MkEff resTy e'} -> EffM m t (e :: es) (\v => e :: es) -> EffM m t es (\v11 => es)
pure : a -> EffM m a xs (\v => xs)
pureM : (val : a) -> EffM m a (xs val) xs
rebuildEnv : Env m ys' -> (prf : SubList ys xs) -> Env m xs -> Env m (updateWith ys' xs prf)

  Put things back, replacing old with new in the sub-environment

replaceEnvAt : (x : a) -> (idx : SubElem x' xs) -> Env m ys -> Env m (updateAt idx a ys)
resourceType : EFFECT -> Type

  Get the resource type (handy at the REPL to find out about an effect)

run : Applicative m => (prog : EffM m a xs xs') -> {default missing pretty-printer for term env : Env m xs} -> m a

  Run an effectful program.

  The content (`m`) in which to run the program is taken from the
  environment in which the program is called. The `env` argument is
  implicit and initialised automatically.

  prog

    The effectful program to run.

runEnv : Applicative m => Env m xs -> EffM m a xs xs' -> m (x : a ** Env m (xs' x))

  Similar to 'runInit', but take the result of `Env`.

runInit : Applicative m => (env : Env m xs) -> (prog : EffM m a xs xs') -> m a

  Run an effectful program in a given context `m` with a default value for the environment.

  This is useful for when there is no default environment for the given context.

  env

    The environment to use.

  prog

    The effectful program to run.

runPure : (prog : EffM id a xs xs') -> {default missing pretty-printer for term env : Env id xs} -> a

  Run an effectful program in the identity context.

  A helper function useful for when the given context is 'pure'.
  The `env` argument is implicit and initialised automatically.

  prog

    The effectful program to run.

runPureEnv : (env : Env id xs) -> (prog : EffM id a xs xs') -> (x : a ** Env id (xs' x))

  Similar to 'runEnv', but the context (m) is 'pure'

runPureInit : (env : Env id xs) -> (prog : EffM id a xs xs') -> a

  Run an effectful program with a given default value for the environment.

  A helper function useful for when the given context is 'pure' and there is no default environment.

  env

    The environment to use.

  prog

    The effectful program to run.

runWith : (a -> m a) -> Env m xs -> EffM m a xs xs' -> m a
staticEff : EffM m a xs (\v => xs) -> EffM m a xs (\v5 => xs)

  Run a subprogram which results in an effect state the same as the input.

subListId : (xs : List a) -> SubList xs xs
toEff : (xs' : List EFFECT) -> EffM m a xs (\v => xs') -> EffM m a xs (\v6 => xs')

  Explicitly give the expected set of result effects for an effectful
  operation.

updateAt : (idx : SubElem x' xs) -> (a : Type) -> List EFFECT -> List EFFECT
updateResTy : (val : t) -> (xs : List EFFECT) -> Elem (MkEff a e) xs -> e t a b -> List EFFECT
updateWith : (ys' : List EFFECT) -> (xs : List EFFECT) -> SubList ys xs -> List EFFECT
when : Bool -> Lazy (EffM m () xs (\underscore => xs)) -> EffM m () xs (\underscore => xs)