module Inception.Cont.Base where
open import Level
open import Data.Unit
open import Data.Product as P
open import Function as F
open import Data.Sum as S
open import Relation.Binary.PropositionalEquality
open import Inception.Prelude
K[_] : ∀ {v x} -> Set v -> Set x -> Set (v ⊔ x)
K[ V ] X = V ^ V ^ X
open import Inception.Monad.Base
K[_]-Monad : ∀ {v x} -> (V : Set v) -> Monad {x = x} {y = v ⊔ x} K[ V ]
K[ V ]-Monad .η a k = k a
K[ V ]-Monad ._* f m k = m \a -> f a k
K[ V ]-Monad .unitl a = refl
K[ V ]-Monad .unitr f = refl
K[ V ]-Monad .assoc f g = refl
cocurry : ∀ {v x} -> {V : Set v} {X Y Z : Set x} -> (Z × V ^ X -> K[ V ] Y) -> Z -> K[ V ] (X ⊎ Y)
cocurry f z k = f (z , k ∘ inj₁) (k ∘ inj₂)
councurry : ∀ {v x} -> {V : Set v} {X Y Z : Set x} -> (Z -> K[ V ] (X ⊎ Y)) -> Z × V ^ X -> K[ V ] Y
councurry g (z , k₁) k₂ = g z S.[ k₁ , k₂ ]
[]~ : ∀ {v x} -> {V : Set v} {X : Set x} -> V -> K[ V ] X
[]~ v k = v
inc1 : ∀ {v x} -> {V : Set v} {X : Set x} -> (K[ V ] X) ^ V -> K[ V ] (⊤ ⊎ X)
inc1 f k = f (k (inj₁ tt)) (k ∘ inj₂)
incP : ∀ {v p x} -> {V : Set v} {P : Set p} {X : Set x} -> (K[ V ] X) ^ (V ^ P) -> K[ V ] (P ⊎ X)
incP f k = f (k ∘ inj₁) (k ∘ inj₂)