{-# OPTIONS --no-termination-check #-}

open import Prelude
open import Algebra

module Hyper.Comonadic {g} {𝐺 : Type g  Type g} (comon : Comonad 𝐺) where

open Comonad comon

infixr 0 _↬_ _↬′_
_↬′_ : Type g  Type g  Type g


{-# NO_POSITIVITY_CHECK #-}
record _↬_ (A : Type g) (B : Type g) : Type g where
  inductive
  infixl 4 _·_
  field _·_ : 𝐺 (B ↬′ A)  B
open _↬_

A ↬′ B = B  A  B

infixr 9 _⊙_ _⊙′_
mutual
  _⊙′_ : B  C  𝐺 (A ↬′ B)  𝐺 (A ↬′ C)
  f ⊙′ g = extend  g′ g″  f · cmap  f′ k  f′ (g″  k)) g′) g

  _⊙_ : B  C  A  B  A  C
  (f  g) · k = f · (g ⊙′ k)

𝕀 : A  A
𝕀 · x = extract x 𝕀

_◃_ : (𝐺 A  B)  A  B  A  B
(f  h) · k = f (cmap (_$ h) k)

 : (𝐺 A  B)  A  B
 f = f  ( f)

k : A  B  A
k x · _ = x

 : A  B  𝐺 A  B
 h x = h · cmap const x

cata : {C : Type g}  ((𝐺 (C  A)  B)  C)  A  B  C
cata ϕ h = ϕ λ k  h · cmap (_∘ cata ϕ) k

ana : {C : Type g}  (C  𝐺 (C  A)  B)  C  A  B
ana ψ r · k = ψ r (cmap (_∘ ana ψ) k)

_◂_▸_ :  {A′ B′}  (𝐺 B  B′)  A  B  (𝐺 A′  A)  A′  B′
f  h  g =  f  h   g