{-# OPTIONS --no-termination-check #-} module Hyper.NonPositive where open import Prelude infixr 2 _↬_ {-# NO_POSITIVITY_CHECK #-} record _↬_ (A : Type a) (B : Type b) : Type (a ℓ⊔ b) where constructor Φ; inductive infixl 4 _·_ field _·_ : (B ↬ A) → B open _↬_ public _⊙_ : B ↬ C → A ↬ B → A ↬ C (f ⊙ g) · k = f · (g ⊙ k) 𝕀 : A ↬ A 𝕀 · k = k · 𝕀 𝕂 : A ↬ B ↬ A 𝕂 · x · y = x · 𝕂 infixr 4 _◃_ _◃_ : (A → B) → A ↬ B → A ↬ B (f ◃ h) · k = f (k · h) infixl 4 _▹_ _▹_ : A ↬ B → (B → A) → A ↬ B h ▹ f · k = h · (f ◃ k) _◂_▸_ : ∀ {a′ b′} {A′ : Type a′} {B′ : Type b′} → (B → B′) → A ↬ B → (A′ → A) → A′ ↬ B′ (f ◂ h ▸ g) · k = f (h · (g ◂ k ▸ f)) mutual infixr 4 _◂_ _◂_ : (B → C) → A ↬ B → A ↬ C (f ◂ h) · k = f (h · (k ▸ f)) infixl 4 _▸_ _▸_ : (B ↬ C) → (A → B) → A ↬ C h ▸ f · k = h · (f ◂ k) △ : (A → B) → A ↬ B △ f = f ◃ △ f k : A → B ↬ A k x · _ = x ▽ : A ↬ B → A → B ▽ h x = h · k x ana : (A → (A → B) → C) → A → B ↬ C ana ψ x · y = ψ x (λ z → y · ana ψ z) cata : (((A → B) → C) → A) → B ↬ C → A cata ϕ h = ϕ λ g → h · Φ (g ∘ cata ϕ) unroll : A ↬ B → (A ↬ B → A) → B unroll x f = x · Φ f roll : ((A ↬ B → A) → B) → A ↬ B roll f · k = f (k ·_) 𝕊 : A ↬ (B → C) → A ↬ B → A ↬ C 𝕊 = curry (ana λ { (i , j) fga → (i · Φ (fga ∘ (_, j))) (j · Φ (fga ∘ (i ,_))) }) 𝕄 : A ↬ A ↬ B → A ↬ B 𝕄 h · k = h · Φ (λ x → k · 𝕄 x) · k Producer : Type a → Type b → Type (a ℓ⊔ b) Producer A B = (A → B) ↬ B Consumer : Type a → Type b → Type (a ℓ⊔ b) Consumer A B = B ↬ (A → B) yield : A → Producer A B → Producer A B yield x prod · cons = (cons · prod) x await : (A → B → B) → Consumer A B → Consumer A B (await f cons · prod) x = f x (prod · cons) open import Data.List zipˡ : List A → Producer A (List (A × B)) zipˡ = foldr yield (k []) zipʳ : List B → Consumer A (List (A × B)) zipʳ = foldr (λ y → await (λ x xs → (x , y) ∷ xs)) (k λ _ → []) zipʰ : List A → List B → List (A × B) zipʰ xs ys = zipˡ xs · zipʳ ys open import Relation.Binary module Sorting {ℓ} {E : Type ℓ} (tot : TotalOrder E ℓzero ℓzero) where open TotalOrder tot nilˡ : Producer (Maybe E) (List E) nilˡ · yk = (yk · nilˡ) nothing mergeˡ : List E → Producer (Maybe E) (List E) mergeˡ = foldr (yield ∘ just) nilˡ nilʳ : Consumer (Maybe E) (List E) (nilʳ · xs) nothing = [] (nilʳ · xs) (just x) = x ∷ (xs · nilʳ) merge¹ : E → Consumer (Maybe E) (List E) → Consumer (Maybe E) (List E) (merge¹ y yk · xk) nothing = y ∷ (xk · yk) (merge¹ y yk · xk) (just x) with x ≤? y ... | yes x≤y = x ∷ (xk · merge¹ y yk) ... | no x≰y = y ∷ (yk · xk) (just x) mergeʳ : List E → Consumer (Maybe E) (List E) mergeʳ = foldr merge¹ nilʳ