88
99module Data.Container.FreeMonad where
1010
11- open import Level
11+ open import Level using (Level; _⊔_)
1212open import Data.Sum.Base using (inj₁; inj₂ ; [_,_]′)
13- open import Data.Product
14- open import Data.Container
13+ open import Data.Product using (_,_; -,_)
14+ open import Data.Container using (Container; ⟦_⟧; μ)
15+ open import Data.Container.Relation.Unary.All using (□; all)
1516open import Data.Container.Combinator using (const; _⊎_)
16- open import Data.W using (sup)
17- open import Effect.Monad
17+ open import Data.W as W using (sup)
18+ open import Effect.Functor using (RawFunctor)
19+ open import Effect.Applicative using (RawApplicative)
20+ open import Effect.Monad using (RawMonad)
21+ open import Function.Base as Function using (_$_; _∘_)
22+
23+ variable
24+ x y s p ℓ : Level
25+ C : Container s p
26+ X : Set x
27+ Y : Set y
1828
1929infixl 1 _⋆C_
2030infix 1 _⋆_
@@ -29,28 +39,89 @@ infix 1 _⋆_
2939-- A useful intuition is to think of containers describing single
3040-- operations and the free monad construction over a container and a set
3141-- describing a tree of operations as nodes and elements of the set as
32- -- leafs . If one starts at the root, then any path will pass finitely
42+ -- leaves . If one starts at the root, then any path will pass finitely
3343-- many nodes (operations described by the container) and eventually end
3444-- up in a leaf (element of the set) -- hence the Kleene star notation
3545-- (the type can be read as a regular expression).
3646
47+ ------------------------------------------------------------------------
48+ -- Type definition
49+
50+ -- The free moand can be defined as the least fixpoint `μ (C ⋆C X)`
51+
3752_⋆C_ : ∀ {x s p} → Container s p → Set x → Container (s ⊔ x) p
3853C ⋆C X = const X ⊎ C
3954
40- _⋆_ : ∀ {x s p} → Container s p → Set x → Set (x ⊔ s ⊔ p)
41- C ⋆ X = μ (C ⋆C X)
55+ -- However Agda's positivity checker is currently too weak to observe
56+ -- that `X` is used in a strictly positive manner in `μ (C ⋆C X)` as
57+ -- demonstrated in #693.
58+ -- So we provide instead an inductive definition that we prove to be
59+ -- equivalent to the μ-based one.
60+
61+ data _⋆_ (C : Container s p) (X : Set x) : Set (x ⊔ s ⊔ p) where
62+ pure : X → C ⋆ X
63+ impure : ⟦ C ⟧ (C ⋆ X) → C ⋆ X
64+
65+ ------------------------------------------------------------------------
66+ -- Equivalent types
67+
68+ -- We can prove that `C ⋆ X` is equivalent to one layer of `C ⋆C X` with
69+ -- subterms of tyep `C ⋆ X`.
70+
71+ inj : {X : Set x} → ⟦ C ⋆C X ⟧ (C ⋆ X) → C ⋆ X
72+ inj (inj₁ x , _) = pure x
73+ inj (inj₂ c , r) = impure (c , r)
74+
75+ out : {X : Set x} → C ⋆ X → ⟦ C ⋆C X ⟧ (C ⋆ X)
76+ out (pure x) = inj₁ x , λ ()
77+ out (impure (c , r)) = inj₂ c , r
78+
79+ -- We can fully convert back and forth between `C ⋆ X` and `μ (C ⋆C X)`.
4280
43- module _ {s p} {C : Container s p} where
81+ toμ : C ⋆ X → μ (C ⋆C X)
82+ toμ (pure x) = sup (inj₁ x , λ ())
83+ toμ (impure (c , r)) = sup (inj₂ c , toμ ∘ r)
84+
85+ fromμ : μ (C ⋆C X) → C ⋆ X
86+ fromμ = W.foldr inj
87+
88+ -- We can recover an induction principle similar to the one given in `Data.W`.
89+ -- We curry these ones by distinguishing the pure vs. impure case
90+
91+ module _ (P : C ⋆ X → Set ℓ)
92+ (algP : ∀ x → P (pure x))
93+ (algI : ∀ {t} → □ C P t → P (impure t)) where
94+
95+ induction : (t : C ⋆ X) → P t
96+ induction (pure x) = algP x
97+ induction (impure (c , r)) = algI $ all (induction ∘ r)
98+
99+ module _ {P : Set ℓ}
100+ (algP : X → P)
101+ (algI : ⟦ C ⟧ P → P) where
102+
103+ foldr : C ⋆ X → P
104+ foldr = induction (Function.const P) algP (algI ∘ -,_ ∘ □.proof)
105+
106+ _<$>_ : (X → Y) → C ⋆ X → C ⋆ Y
107+ f <$> t = foldr (pure ∘ f) impure t
108+
109+ _<*>_ : C ⋆ (X → Y) → C ⋆ X → C ⋆ Y
110+ pure f <*> t = f <$> t
111+ impure (c , r) <*> t = impure (c , λ v → r v <*> t)
112+
113+ _>>=_ : C ⋆ X → (X → C ⋆ Y) → C ⋆ Y
114+ pure x >>= f = f x
115+ impure (c , r) >>= f = impure (c , λ v → r v >>= f)
116+
117+ ------------------------------------------------------------------------
118+ -- Structure
44119
45- inn : ∀ {x} {X : Set x} → ⟦ C ⟧ (C ⋆ X) → C ⋆ X
46- inn (s , f) = sup (inj₂ s , f)
120+ rawFunctor : RawFunctor (_⋆_ {x = x} C)
121+ rawFunctor = record { _<$>_ = _<$>_ }
47122
48- rawMonad : ∀ {x} → RawMonad {s ⊔ p ⊔ x} (C ⋆_)
49- rawMonad = record { return = return; _>>=_ = _>>=_ }
50- where
51- return : ∀ {X} → X → C ⋆ X
52- return x = sup (inj₁ x , λ ())
123+ rawApplicative : {C : Container s p} → RawApplicative (_⋆_ {x = x ⊔ s ⊔ p} C)
124+ rawApplicative = record { pure = pure ; _⊛_ = _<*>_ }
53125
54- _>>=_ : ∀ {X Y} → C ⋆ X → (X → C ⋆ Y) → C ⋆ Y
55- sup (inj₁ x , _) >>= k = k x
56- sup (inj₂ s , f) >>= k = inn (s , λ p → f p >>= k)
126+ rawMonad : {C : Container s p} → RawMonad (_⋆_ {x = x ⊔ s ⊔ p} C)
127+ rawMonad = record { return = pure ; _>>=_ = _>>=_ }
0 commit comments