{-# OPTIONS --no-termination-check #-}
module Hyper.NonStrictPositive where
open import Prelude
infixr 0 _↬_ _↬′_
_↬′_ : Type a → Type b → Type (a ℓ⊔ b)
{-# NO_POSITIVITY_CHECK #-}
record _↬_ (A : Type a) (B : Type b) : Type (a ℓ⊔ b) where
inductive
infixl 4 _·_
field _·_ : (k : B ↬′ A) → B
A ↬′ B = (k : B ↬ A) → B
open _↬_ public
infixl 4 _·′_
_·′_ : (A → B) → (A → B)
_·′_ = id
{-# INLINE _·′_ #-}
infixr 9 _⊙_
_⊙_ : B ↬ C → A ↬ B → A ↬ C
f₁ ⊙ f₂ · f₃ = f₁ · λ f₄ → f₂ · λ f₅ → f₃ ·′ (f₄ ⊙ f₅)
cata : (((C → A) → B) → C) → A ↬ B → C
cata ϕ h = ϕ λ k → h · k ∘ cata ϕ
ana : (C → (C → A) → B) → C → A ↬ B
ana ψ r · k = ψ r (k ∘ ana ψ)
𝕀 : A ↬ A
𝕀 · x = x ·′ 𝕀
𝕀′ : A ↬′ A
𝕀′ x = x · 𝕀′
pure : A → B ↬ A
pure x · _ = x
𝕂 : A ↬ B ↬ A
𝕂 · x · y = x ·′ 𝕂
_<*>_ : A ↬ (B → C) → A ↬ B → A ↬ C
_<*>_ = curry (ana λ { (i , j) fga → (i · fga ∘ (_, j)) (j · fga ∘ (i ,_)) })
𝕄 : A ↬ A ↬ B → A ↬ B
𝕄 = cata λ where g · k → g ·′ k · k
_◃_ : (A → B) → A ↬ B → A ↬ B
(f ◃ h) · k = f (k ·′ h)
△ : (A → B) → A ↬ B
△ f = f ◃ △ f
▽ : A ↬ B → A → B
▽ h x = h · λ _ → x
infixr 2 _↝_
data Tree (A : Type a) : Type a where
[_] : A → Tree A
_↝_ : Tree A → Tree A → Tree A
⟦_⟧ₜ : Tree (Type a) → Type a
⟦ [ A ] ⟧ₜ = A
⟦ x ↝ y ⟧ₜ = ⟦ x ⟧ₜ → ⟦ y ⟧ₜ
⟦_⟧ₕ : Tree (Type a) → Type a
⟦ [ A ] ⟧ₕ = A
⟦ x ↝ y ⟧ₕ = ⟦ x ⟧ₕ ↬ ⟦ y ⟧ₕ
mutual
⟦_⟧↑ : (t : Tree (Type a)) → ⟦ t ⟧ₜ → ⟦ t ⟧ₕ
⟦ [ _ ] ⟧↑ x = x
⟦ x ↝ y ⟧↑ f = △ (⟦ y ⟧↑ ∘ f ∘ ⟦ x ⟧↓)
⟦_⟧↓ : (t : Tree (Type a)) → ⟦ t ⟧ₕ → ⟦ t ⟧ₜ
⟦ [ _ ] ⟧↓ x = x
⟦ x ↝ y ⟧↓ f = ⟦ y ⟧↓ ∘ ▽ f ∘ ⟦ x ⟧↑
module _ {A B C : Type a} where
𝕊 : (A ↬ B ↬ C) ↬ (A ↬ B) ↬ A ↬ C
𝕊 = ⟦ ([ A ] ↝ [ B ] ↝ [ C ]) ↝ ([ A ] ↝ [ B ]) ↝ [ A ] ↝ [ C ] ⟧↑ λ x y z → (x z) (y z)
run : A ↬ A → A
run h = h · 𝕀′
eval : ((A ↬ B) × A) ↬ B
eval · k = uncurry ▽ (k eval)