open Lean
/- Disable the automatic monadic lifting feature described in the paper. We want to make it clear that we do not depend on it. -/set_option autoLift falsedef
runCatch: {m : Type u_1 → Type u_2} → {α : Type u_1} → [inst : Monad m] → ExceptT α m α → m α
runCatch [
Monad: (Type ?u.9 → Type ?u.8) → Type (max (?u.9 + 1) ?u.8)
Monad
m: Type u_1 → Type u_2
m] (
x: ExceptT α m α
x :
ExceptT: Type u_1 → (Type u_1 → Type u_2) → Type u_1 → Type u_2
ExceptT
α: Type u_1
α
m: Type u_1 → Type u_2
m
α: Type u_1
α) :
m: Type u_1 → Type u_2
m
α: Type u_1
α :=
ExceptT.run: {ε : Type u_1} → {m : Type u_1 → Type u_2} → {α : Type u_1} → ExceptT ε m α → m (Except ε α)
ExceptT.run
x: ExceptT α m α
x>>=fun|
Except.ok: {ε : Type ?u.57} → {α : Type ?u.56} → α → Except ε α
Except.ok
x: α
x=>
pure: {f : Type u_1 → Type u_2} → [self : Pure f] → {α : Type u_1} → α → f α
pure
x: α
x|
Except.error: {ε : Type ?u.115} → {α : Type ?u.114} → ε → Except ε α
Except.error
e: α
e=>
pure: {f : Type u_1 → Type u_2} → [self : Pure f] → {α : Type u_1} → α → f α
Monad: (Type ?u.3135 → Type ?u.3134) → Type (max (?u.3135 + 1) ?u.3134)
Monad
m: Type ?u.2574 → Type ?u.2573
m]
variable (
ma: m α
ma
ma': m α
ma' :
m: Type ?u.2585 → Type ?u.2584
m
α: Type ?u.2585
α)
variable (
b: Bool
b :
Bool: Type
Bool)
example: ∀ {m : Type u_1 → Type u_2} {α : Type u_1} [inst : Monad m] (ma : m α) [inst_1 : LawfulMonad m],
(ExceptCpsT.runCatch do
let x ← ExceptCpsT.lift ma
throw x) =
ma
example [
LawfulMonad: (m : Type u_1 → Type u_2) → [inst : Monad m] → Prop
LawfulMonad
m: Type u_1 → Type u_2
m] :
(do'let
x: α
x←
ma: m α
ma;return
x: α
x)
=
ma: m α
ma
:=
m: Type?u.2639 →Type?u.2638 α: Type?u.2639 inst✝¹: Monad m ma, ma': m α b: Bool
(ExceptCpsT.runCatch dolet x ← ExceptCpsT.lift ma
throw x) =
ma
Goals accomplished!🐙
example: Id.run
(ExceptCpsT.runCatch do
let x ← ExceptCpsT.lift (pure 1)
throw x) =
1
example :
Id.run: {α : Type} → Id α → α
Id.run
(do'let
x: Nat
x :=
1: Nat
1;return
x: Nat
x)=
1: Nat
1
:=
rfl: ∀ {α : Type} {a : α}, a = a
rfl
example: ∀ {m : Type → Type u_1} {α : Type} [inst : Monad m] (ma ma' : m α) (b : Bool) [inst_1 : LawfulMonad m],
(ExceptCpsT.runCatch do
if b = true then do
let x ← ExceptCpsT.lift ma
throw x
else ExceptCpsT.lift (pure ())
ExceptCpsT.lift ma') =
if b = true then ma else ma'
example [
LawfulMonad: (m : Type → Type u_1) → [inst : Monad m] → Prop
LawfulMonad
m: Type → Type u_1
m] :
(do'if
b: Bool
bthen {
let
x: α
x←
ma: m α
ma;return
x: α
x
};
ma': m α
ma')
=
(if
b: Bool
bthen
ma: m α
maelse
ma': m α
ma')
:=
m: Type→Type?u.3364 α: Type inst✝¹: Monad m ma, ma': m α b: Bool
(ExceptCpsT.runCatch doif b = true thendolet x ← ExceptCpsT.lift ma
throw x
else ExceptCpsT.lift (pure ())
ExceptCpsT.lift ma') =if b = true then ma else ma'
m: Type→Type?u.3364 α: Type inst✝¹: Monad m ma, ma': m α
false
(ExceptCpsT.runCatch doif false = true thendolet x ← ExceptCpsT.lift ma
throw x
else ExceptCpsT.lift (pure ())
ExceptCpsT.lift ma') =if false = true then ma else ma'
m: Type→Type?u.3364 α: Type inst✝¹: Monad m ma, ma': m α
(ExceptCpsT.runCatch doif true = true thendolet x ← ExceptCpsT.lift ma
throw x
else ExceptCpsT.lift (pure ())
ExceptCpsT.lift ma') =if true = true then ma else ma'
m: Type→Type?u.3364 α: Type inst✝¹: Monad m ma, ma': m α
false
(ExceptCpsT.runCatch doif false = true thendolet x ← ExceptCpsT.lift ma
throw x
else ExceptCpsT.lift (pure ())
ExceptCpsT.lift ma') =if false = true then ma else ma'
m: Type→Type?u.3364 α: Type inst✝¹: Monad m ma, ma': m α
(ExceptCpsT.runCatch doif true = true thendolet x ← ExceptCpsT.lift ma
throw x
else ExceptCpsT.lift (pure ())
ExceptCpsT.lift ma') =if true = true then ma else ma'
Goals accomplished!🐙
example: ∀ {m : Type u_1 → Type u_2} {α : Type u_1} [inst : Monad m] (ma ma' : m α) (b : Bool) [inst_1 : LawfulMonad m],
(ExceptCpsT.runCatch do
let y ←
if b = true then do
let x ← ExceptCpsT.lift ma
throw x
else ExceptCpsT.lift ma'
ExceptCpsT.lift (pure y)) =
if b = true then ma else ma'
example [
LawfulMonad: (m : Type u_1 → Type u_2) → [inst : Monad m] → Prop
LawfulMonad
m: Type u_1 → Type u_2
m] :
(do'let
y: α
y←if
b: Bool
bthen {
let
x: α
x←
ma: m α
ma;return
x: α
x
} else {
ma': m α
ma'
};
pure: {f : Type u_1 → Type u_2} → [self : Pure f] → {α : Type u_1} → α → f α
pure
y: α
y)
=
(if
b: Bool
bthen
ma: m α
maelse
ma': m α
ma')
:=
m: Type?u.4867 →Type?u.4866 α: Type?u.4867 inst✝¹: Monad m ma, ma': m α b: Bool
(ExceptCpsT.runCatch dolet y ←if b = true thendolet x ← ExceptCpsT.lift ma
throw x
else ExceptCpsT.lift ma'
ExceptCpsT.lift (pure y)) =if b = true then ma else ma'
m: Type?u.4867 →Type?u.4866 α: Type?u.4867 inst✝¹: Monad m ma, ma': m α
false
(ExceptCpsT.runCatch dolet y ←if false = true thendolet x ← ExceptCpsT.lift ma
throw x
else ExceptCpsT.lift ma'
ExceptCpsT.lift (pure y)) =if false = true then ma else ma'
m: Type?u.4867 →Type?u.4866 α: Type?u.4867 inst✝¹: Monad m ma, ma': m α
(ExceptCpsT.runCatch dolet y ←if true = true thendolet x ← ExceptCpsT.lift ma
throw x
else ExceptCpsT.lift ma'
ExceptCpsT.lift (pure y)) =if true = true then ma else ma'
m: Type?u.4867 →Type?u.4866 α: Type?u.4867 inst✝¹: Monad m ma, ma': m α
false
(ExceptCpsT.runCatch dolet y ←if false = true thendolet x ← ExceptCpsT.lift ma
throw x
else ExceptCpsT.lift ma'
ExceptCpsT.lift (pure y)) =if false = true then ma else ma'
m: Type?u.4867 →Type?u.4866 α: Type?u.4867 inst✝¹: Monad m ma, ma': m α
(ExceptCpsT.runCatch dolet y ←if true = true thendolet x ← ExceptCpsT.lift ma
throw x
else ExceptCpsT.lift ma'
ExceptCpsT.lift (pure y)) =if true = true then ma else ma'