Theorem: CategoryTheory.eq_inverse_map
File: Mathlib/CategoryTheory/Monad/Types.lean

Proof steps:
state_before: m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : KleisliCat m
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
⊢ { obj := fun X => X, map := fun {X Y} f => f }.map (f ≫ g) =
    { obj := fun X => X, map := fun {X Y} f => f }.map f ≫ { obj := fun X => X, map := fun {X Y} f => f }.map g
state_after: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : KleisliCat m
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ { obj := fun X => X, map := fun {X Y} f => f }.map (f ≫ g) t =
    ({ obj := fun X => X, map := fun {X Y} f => f }.map f ≫ { obj := fun X => X, map := fun {X Y} f => f }.map g) t
tactic: funext t
state_before: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : KleisliCat m
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ { obj := fun X => X, map := fun {X Y} f => f }.map (f ≫ g) t =
    ({ obj := fun X => X, map := fun {X Y} f => f }.map f ≫ { obj := fun X => X, map := fun {X Y} f => f }.map g) t
state_after: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : KleisliCat m
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ { obj := fun X => X, map := fun {X Y} f => f }.map (f ≫ g) t = joinM (g <$> f t)
tactic: change _ = joinM (g <$> (f t))
state_before: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : KleisliCat m
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ { obj := fun X => X, map := fun {X Y} f => f }.map (f ≫ g) t = joinM (g <$> f t)
state_after: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : KleisliCat m
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ (f ≫ g) t = f t >>= g
tactic: simp only [joinM, seq_bind_eq, Function.id_comp]
state_before: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : KleisliCat m
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ (f ≫ g) t = f t >>= g
state_after: no goals
tactic: rfl
state_before: m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
⊢ { obj := fun X => X, map := fun {X Y} f => f }.map (f ≫ g) =
    { obj := fun X => X, map := fun {X Y} f => f }.map f ≫ { obj := fun X => X, map := fun {X Y} f => f }.map g
state_after: m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
this : _root_.Monad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
⊢ { obj := fun X => X, map := fun {X Y} f => f }.map (f ≫ g) =
    { obj := fun X => X, map := fun {X Y} f => f }.map f ≫ { obj := fun X => X, map := fun {X Y} f => f }.map g
tactic: letI : _root_.Monad (ofTypeMonad m).obj :=
          show _root_.Monad m from inferInstance
state_before: m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
this : _root_.Monad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
⊢ { obj := fun X => X, map := fun {X Y} f => f }.map (f ≫ g) =
    { obj := fun X => X, map := fun {X Y} f => f }.map f ≫ { obj := fun X => X, map := fun {X Y} f => f }.map g
state_after: m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
this✝ : _root_.Monad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
this : LawfulMonad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
⊢ { obj := fun X => X, map := fun {X Y} f => f }.map (f ≫ g) =
    { obj := fun X => X, map := fun {X Y} f => f }.map f ≫ { obj := fun X => X, map := fun {X Y} f => f }.map g
tactic: letI : LawfulMonad (ofTypeMonad m).obj :=
          show LawfulMonad m from inferInstance
state_before: m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
this✝ : _root_.Monad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
this : LawfulMonad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
⊢ { obj := fun X => X, map := fun {X Y} f => f }.map (f ≫ g) =
    { obj := fun X => X, map := fun {X Y} f => f }.map f ≫ { obj := fun X => X, map := fun {X Y} f => f }.map g
state_after: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
this✝ : _root_.Monad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
this : LawfulMonad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ { obj := fun X => X, map := fun {X Y} f => f }.map (f ≫ g) t =
    ({ obj := fun X => X, map := fun {X Y} f => f }.map f ≫ { obj := fun X => X, map := fun {X Y} f => f }.map g) t
tactic: funext t
state_before: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
this✝ : _root_.Monad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
this : LawfulMonad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ { obj := fun X => X, map := fun {X Y} f => f }.map (f ≫ g) t =
    ({ obj := fun X => X, map := fun {X Y} f => f }.map f ≫ { obj := fun X => X, map := fun {X Y} f => f }.map g) t
state_after: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
this✝ : _root_.Monad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
this : LawfulMonad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ (f ≫ g) t = (f ≫ g) t
tactic: dsimp
state_before: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
this✝ : _root_.Monad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
this : LawfulMonad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ (f ≫ g) t = (f ≫ g) t
state_after: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
this✝ : _root_.Monad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
this : LawfulMonad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ joinM (g <$> f t) = (f ≫ g) t
tactic: change joinM (g <$> (f t)) = _
state_before: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
this✝ : _root_.Monad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
this : LawfulMonad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ joinM (g <$> f t) = (f ≫ g) t
state_after: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
this✝ : _root_.Monad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
this : LawfulMonad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ f t >>= g = (f ≫ g) t
tactic: simp only [joinM, seq_bind_eq, Function.id_comp]
state_before: case h
m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ Z✝ : Kleisli (ofTypeMonad m)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
this✝ : _root_.Monad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
this : LawfulMonad (ofTypeMonad m).obj :=
  let_fun this := inferInstance;
  this
t : { obj := fun X => X, map := fun {X Y} f => f }.obj X✝
⊢ f t >>= g = (f ≫ g) t
state_after: no goals
tactic: rfl
state_before: m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
⊢ 𝟭 (KleisliCat m) ≅
    { obj := fun X => X, map := fun {X Y} f => f, map_id := ⋯, map_comp := ⋯ } ⋙
      { obj := fun X => X, map := fun {X Y} f => f, map_id := ⋯, map_comp := ⋯ }
state_after: m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ : KleisliCat m
f : X✝ ⟶ Y✝
⊢ (𝟭 (KleisliCat m)).map f ≫ ((fun X => Iso.refl X) Y✝).hom =
    ((fun X => Iso.refl X) X✝).hom ≫
      ({ obj := fun X => X, map := fun {X Y} f => f, map_id := ⋯, map_comp := ⋯ } ⋙
            { obj := fun X => X, map := fun {X Y} f => f, map_id := ⋯, map_comp := ⋯ }).map
        f
tactic: refine NatIso.ofComponents (fun X => Iso.refl X) fun f => ?_
state_before: m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ : KleisliCat m
f : X✝ ⟶ Y✝
⊢ (𝟭 (KleisliCat m)).map f ≫ ((fun X => Iso.refl X) Y✝).hom =
    ((fun X => Iso.refl X) X✝).hom ≫
      ({ obj := fun X => X, map := fun {X Y} f => f, map_id := ⋯, map_comp := ⋯ } ⋙
            { obj := fun X => X, map := fun {X Y} f => f, map_id := ⋯, map_comp := ⋯ }).map
        f
state_after: m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ : KleisliCat m
f : X✝ ⟶ Y✝
⊢ f >=> pure = pure >=> f
tactic: change f >=> pure = pure >=> f
state_before: m : Type u → Type u
inst✝¹ : _root_.Monad m
inst✝ : LawfulMonad m
X✝ Y✝ : KleisliCat m
f : X✝ ⟶ Y✝
⊢ f >=> pure = pure >=> f
state_after: no goals
tactic: simp [functor_norm]