{-# 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) }