{-# OPTIONS --no-positivity-check --allow-unsolved-metas #-} open import Prelude open import Algebra module Control.Comonad.Cofree where module Comonadic {ββ ββ} {π : Type ββ} {π : π β Type ββ β Type ββ} (mon : Monoid π) (comon : GradedComonad mon π) {πΉ : Type (ββ ββ ββ) β Type ββ} (functor : Functor πΉ) where open Monoid mon open GradedComonad comon renaming (map to cmap) open Functor functor renaming (map to fmap) record CofreeF (A : Type ββ) : Type ββ where constructor _β_ coinductive field head : A step : πΉ (β y Γ π y (CofreeF A)) open CofreeF public Cofree : Type ββ β Type ββ Cofree A = π Ξ΅ (CofreeF A) extractβ² : Cofree A β A extractβ² = head β extract {-# TERMINATING #-} extendβ² : β {x} β (Cofree A β B) β π x (CofreeF A) β π x (CofreeF B) extendβ² k xs = xs =>>[ βΞ΅ _ ] (Ξ» x β k x β fmap (mapβ (extendβ² k)) (step (extract x))) module Monadic {ββ ββ} {π : Type ββ} {π : π β Type ββ β Type ββ} (mon : Monoid π) (monad : GradedMonad mon π) {πΉ : Type (ββ ββ ββ) β Type ββ} (alternative : Alternative πΉ) where open Monoid mon open GradedMonad monad renaming ( map to mmap) open Alternative alternative renaming (map to fmap) record CofreeF (A : Type ββ) : Type ββ where pattern constructor _β_ inductive field head : A step : πΉ (β y Γ π y (CofreeF A)) open CofreeF public Cofree : Type ββ β Type ββ Cofree A = π Ξ΅ (CofreeF A) returnβ² : A β Cofree A returnβ² x = return (x β 0#) {-# TERMINATING #-} bindβ² : β {x} β (A β Cofree B) β π x (CofreeF A) β π x (CofreeF B) bindβ² k xs = xs >>=[ βΞ΅ _ ] Ξ» { (x β xs) β mmap (Ξ» { (y β ys) β y β (ys <|> fmap (mapβ (bindβ² k)) xs) }) (k x) }