8
8
9
9
module Data.Container.FreeMonad where
10
10
11
- open import Level
11
+ open import Level using (Level; _⊔_)
12
12
open 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)
15
16
open 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
18
28
19
29
infixl 1 _⋆C_
20
30
infix 1 _⋆_
@@ -29,28 +39,89 @@ infix 1 _⋆_
29
39
-- A useful intuition is to think of containers describing single
30
40
-- operations and the free monad construction over a container and a set
31
41
-- 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
33
43
-- many nodes (operations described by the container) and eventually end
34
44
-- up in a leaf (element of the set) -- hence the Kleene star notation
35
45
-- (the type can be read as a regular expression).
36
46
47
+ ------------------------------------------------------------------------
48
+ -- Type definition
49
+
50
+ -- The free moand can be defined as the least fixpoint `μ (C ⋆C X)`
51
+
37
52
_⋆C_ : ∀ {x s p} → Container s p → Set x → Container (s ⊔ x) p
38
53
C ⋆C X = const X ⊎ C
39
54
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)`.
42
80
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
44
119
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 { _<$>_ = _<$>_ }
47
122
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 ; _⊛_ = _<*>_ }
53
125
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