Documentation

ToMathlib.Control.FreeMonad

Free Monad of a Functor #

inductive FreeMonad (f : Type u → Type v) (α : Type w) :
Type (max (u + 1) v w)

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.

Instances For
    @[inline]
    def FreeMonad.lift {f : Type u → Type v} {α : Type u} (x : f α) :

    Lift an element of the base functor to the free monad by directly returning the result.

    Equations
    Instances For
      instance FreeMonad.instMonadLift {f : Type u → Type v} :
      Equations
      @[simp]
      theorem FreeMonad.monadLift_eq_lift {f : Type u → Type v} {α : Type u} (x : f α) :
      instance FreeMonad.instInhabited {f : Type u → Type v} {α : Type u} [Inhabited (f α)] :
      Equations
      @[inline]
      def FreeMonad.bind {f : Type u → Type v} {α β : Type u} :
      FreeMonad f α(αFreeMonad f β)FreeMonad f β

      Bind operator on OracleComp spec operation used in the monad definition.

      Equations
      Instances For
        @[simp]
        theorem FreeMonad.bind_pure {f : Type u → Type v} {α β : Type u} (x : α) (r : αFreeMonad f β) :
        @[simp]
        theorem FreeMonad.bind_roll {f : Type u → Type v} {α β γ : Type u} (x : f α) (r : αFreeMonad f β) (g : βFreeMonad f γ) :
        (roll x r).bind g = roll x fun (u : α) => (r u).bind g
        @[simp]
        theorem FreeMonad.bind_lift {f : Type u → Type v} {α β : Type u} (x : f α) (r : αFreeMonad f β) :
        (lift x).bind r = roll x r
        @[simp]
        theorem FreeMonad.monad_pure_def {f : Type u → Type v} {α : Type u} (x : α) :
        @[simp]
        theorem FreeMonad.monad_bind_def {f : Type u → Type v} {α β : Type u} (x : FreeMonad f α) (g : αFreeMonad f β) :
        x >>= g = x.bind g
        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 some x : α Note that we can't use Sort v instead of Prop 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
          Instances For
            @[simp]
            theorem FreeMonad.construct_pure {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)) (y : α) :
            FreeMonad.construct h_pure (fun {β : Type u} => h_roll) (pure y) = h_pure y
            @[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
            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
              Instances For
                @[simp]
                theorem FreeMonad.mapM'_lift {f : Type u → Type v} {α : Type u} {m : Type u → Type w} [Monad m] [LawfulMonad m] (s : {α : Type u} → f αm α) (x : f α) :
                (fun {x : Type u} (x_1 : FreeMonad (fun {α : Type u} => f α) x) => (FreeMonad.mapM' m fun {α : Type u} => s).toFun x_1) (lift x) = s x
                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
                Instances For
                  @[simp]
                  theorem FreeMonad.mapM_pure {f : Type u → Type v} {α : Type u} {m : Type u → Type w} (s : {α : Type u} → f αm α) [Monad m] (x : α) :
                  ((FreeMonad.pure x).mapM fun {α : Type u} => s) = pure x
                  @[simp]
                  theorem FreeMonad.mapM_roll {f : Type u → Type v} {α β : Type u} {m : Type u → Type w} (s : {α : Type u} → f αm α) [Monad m] (x : f α) (r : αFreeMonad f β) :
                  ((roll x r).mapM fun {α : Type u} => s) = do let us x (r u).mapM fun {α : Type u} => s