Free Monad of a Functor #
The free monad on a functor f
is the type freely generated by values of type f α
and the operations pure
and bind
. Implemented directly rather than as a quotient.
Slightly different than constructions of free monads in Haskell because of universe issues.
- pure {f : Type u → Type v} {α : Type w} (x : α) : FreeMonad f α
- roll {f : Type u → Type v} {α : Type w} {β : Type u} (x : f β) (r : β → FreeMonad f α) : FreeMonad f α
Instances For
@[inline]
Lift an element of the base functor to the free monad by directly returning the result.
Equations
Instances For
Equations
- FreeMonad.instMonadLift = { monadLift := fun {α : Type ?u.16} (x : f α) => FreeMonad.lift x }
Equations
- FreeMonad.instInhabited = { default := FreeMonad.lift default }
@[inline]
Bind operator on OracleComp spec
operation used in the monad definition.
Equations
- (FreeMonad.pure x_2).bind x✝ = x✝ x_2
- (FreeMonad.roll x_2 r).bind x✝ = FreeMonad.roll x_2 fun (u : β_1) => (r u).bind x✝
Instances For
@[simp]
Equations
@[simp]
Equations
- One or more equations did not get rendered due to their size.
def
FreeMonad.inductionOn
{f : Type u → Type v}
{α : Type u}
{C : FreeMonad f α → Prop}
(pure : ∀ (x : α), C (pure x))
(roll : ∀ {β : Type u} (x : f β) (r : β → FreeMonad f α), (∀ (y : β), C (r y)) → C (liftM x >>= r))
(oa : FreeMonad f α)
:
C oa
Proving something about FreeMonad f α
only requires two cases:
pure x
for somex : α
Note that we can't useSort v
instead ofProp
due to universe levels.
Equations
- ⋯ = ⋯
Instances For
def
FreeMonad.construct
{f : Type u → Type v}
{α : Type u}
{C : FreeMonad f α → Type u_1}
(pure : (x : α) → C (pure x))
(roll : {β : Type u} → (x : f β) → (r : β → FreeMonad f α) → ((y : β) → C (r y)) → C (liftM x >>= r))
(oa : FreeMonad f α)
:
C oa
Shoulde be possible to unify with the above
Equations
- FreeMonad.construct pure roll (FreeMonad.pure x_1) = pure x_1
- FreeMonad.construct pure roll (FreeMonad.roll x_1 r) = roll x_1 r fun (u : β) => FreeMonad.construct pure (fun {β : Type ?u.429} => roll) (r u)
Instances For
@[simp]
theorem
FreeMonad.construct_roll
{f : Type u → Type v}
{α β : Type u}
{C : FreeMonad f α → Type u_1}
(h_pure : (x : α) → C (pure x))
(h_roll : {β : Type u} → (x : f β) → (r : β → FreeMonad f α) → ((y : β) → C (r y)) → C (liftM x >>= r))
(x : f β)
(r : β → FreeMonad f α)
:
FreeMonad.construct h_pure (fun {β : Type u} => h_roll) (roll x r) = h_roll x r fun (u : β) => FreeMonad.construct h_pure (fun {β : Type u} => h_roll) (r u)
def
FreeMonad.mapM_aux
{f : Type u → Type v}
{α : Type u}
{m : Type u → Type w}
[Pure m]
[Bind m]
(s : {α : Type u} → f α → m α)
(oa : FreeMonad f α)
:
m α
Equations
- FreeMonad.mapM_aux s (FreeMonad.pure x_1) = pure x_1
- FreeMonad.mapM_aux s (FreeMonad.roll x_1 r) = do let u ← s x_1 FreeMonad.mapM_aux (fun {α : Type ?u.55} => s) (r u)
Instances For
def
FreeMonad.mapM'
{f : Type u → Type v}
(m : Type u → Type w)
[Monad m]
[LawfulMonad m]
(s : {α : Type u} → f α → m α)
:
Equations
- FreeMonad.mapM' m s = { toFun := fun {α : Type ?u.14} => FreeMonad.mapM_aux fun {α : Type ?u.14} => s, toFun_pure' := ⋯, toFun_bind' := ⋯ }
Instances For
@[simp]
def
FreeMonad.mapM
{f : Type u → Type v}
{α : Type u}
{m : Type u → Type w}
[Pure m]
[Bind m]
(oa : FreeMonad f α)
(s : {α : Type u} → f α → m α)
:
m α
Canonical mapping of a free monad into any other monad, given a map on the base functor,
Equations
- (FreeMonad.pure x_2).mapM x✝ = pure x_2
- (FreeMonad.roll x_2 r).mapM x✝ = do let u ← x✝ x_2 (r u).mapM fun {α : Type ?u.455} => x✝