Documentation

Mathlib.Data.Option.Basic

Option of a type #

This file develops the basic theory of option types.

If α is a type, then Option α can be understood as the type with one more element than α. Option α has terms some a, where a : α, and none, which is the added element. This is useful in multiple ways:

Part is an alternative to Option that can be seen as the type of True/False values along with a term a : α if the value is True.

theorem Option.coe_def {α : Type u_1} :
(fun (a : α) => some a) = some
theorem Option.mem_map {α : Type u_1} {β : Type u_2} {f : α → β} {y : β} {o : Option α} :
y ∈ Option.map f o ↔ ∃ (x : α), x ∈ o ∧ f x = y
@[simp]
theorem Option.mem_map_of_injective {α : Type u_1} {β : Type u_2} {f : α → β} (H : Function.Injective f) {a : α} {o : Option α} :
f a ∈ Option.map f o ↔ a ∈ o
theorem Option.forall_mem_map {α : Type u_1} {β : Type u_2} {f : α → β} {o : Option α} {p : β → Prop} :
(∀ (y : β), y ∈ Option.map f o → p y) ↔ ∀ (x : α), x ∈ o → p (f x)
theorem Option.exists_mem_map {α : Type u_1} {β : Type u_2} {f : α → β} {o : Option α} {p : β → Prop} :
(∃ (y : β), y ∈ Option.map f o ∧ p y) ↔ ∃ (x : α), x ∈ o ∧ p (f x)
theorem Option.coe_get {α : Type u_1} {o : Option α} (h : o.isSome = true) :
some (o.get h) = o
theorem Option.eq_of_mem_of_mem {α : Type u_1} {a : α} {o1 o2 : Option α} (h1 : a ∈ o1) (h2 : a ∈ o2) :
o1 = o2
theorem Option.Mem.leftUnique {α : Type u_1} :
Relator.LeftUnique fun (x1 : α) (x2 : Option α) => x1 ∈ x2
theorem Option.map_injective {α : Type u_1} {β : Type u_2} {f : α → β} (Hf : Function.Injective f) :

Option.map f is injective if f is injective.

@[simp]
theorem Option.map_comp_some {α : Type u_1} {β : Type u_2} (f : α → β) :
@[simp]
theorem Option.none_bind' {α : Type u_1} {β : Type u_2} (f : α → Option β) :
@[simp]
theorem Option.some_bind' {α : Type u_1} {β : Type u_2} (a : α) (f : α → Option β) :
(some a).bind f = f a
theorem Option.bind_eq_some' {α : Type u_1} {β : Type u_2} {x : Option α} {f : α → Option β} {b : β} :
x.bind f = some b ↔ ∃ (a : α), x = some a ∧ f a = some b
theorem Option.bind_congr' {α : Type u_1} {β : Type u_2} {f g : α → Option β} {x y : Option α} (hx : x = y) (hf : ∀ (a : α), a ∈ y → f a = g a) :
x.bind f = y.bind g
@[deprecated Option.bind_congr (since := "2025-03-20")]
theorem Option.bind_congr'' {α : Type u_1} {β : Type u_2} {f g : α → Option β} {x : Option α} (h : ∀ (a : α), a ∈ x → f a = g a) :
x.bind f = x.bind g
theorem Option.bind_eq_bind' {α β : Type u} {f : α → Option β} {x : Option α} :
x >>= f = x.bind f
theorem Option.map_coe {α β : Type u_5} {a : α} {f : α → β} :
f <$> some a = some (f a)
@[simp]
theorem Option.map_coe' {α : Type u_1} {β : Type u_2} {a : α} {f : α → β} :
Option.map f (some a) = some (f a)

Option.map as a function between functions is injective.

@[simp]
theorem Option.map_inj {α : Type u_1} {β : Type u_2} {f g : α → β} :
@[simp]
theorem Option.map_eq_id {α : Type u_1} {f : α → α} :
theorem Option.map_comm {α : Type u_1} {β : Type u_2} {γ : Type u_3} {δ : Type u_4} {f₁ : α → β} {f₂ : α → γ} {g₁ : β → δ} {g₂ : γ → δ} (h : g₁ ∘ f₁ = g₂ ∘ f₂) (a : α) :
Option.map g₁ (Option.map f₁ (some a)) = Option.map g₂ (Option.map f₂ (some a))
@[simp]
theorem Option.pbind_eq_bind {α : Type u_1} {β : Type u_2} (f : α → Option β) (x : Option α) :
(x.pbind fun (a : α) (x : a ∈ x) => f a) = x.bind f
theorem Option.map_bind' {α : Type u_1} {β : Type u_2} {γ : Type u_3} (f : β → γ) (x : Option α) (g : α → Option β) :
Option.map f (x.bind g) = x.bind fun (a : α) => Option.map f (g a)
theorem Option.pbind_map {α : Type u_1} {β : Type u_2} {γ : Type u_3} (f : α → β) (x : Option α) (g : (b : β) → b ∈ Option.map f x → Option γ) :
(Option.map f x).pbind g = x.pbind fun (a : α) (h : a ∈ x) => g (f a) ⋯
theorem Option.mem_pmem {α : Type u_1} {β : Type u_2} {p : α → Prop} (f : (a : α) → p a → β) (x : Option α) {a : α} (h : ∀ (a : α), a ∈ x → p a) (ha : a ∈ x) :
f a ⋯ ∈ pmap f x h
theorem Option.pmap_bind {α β γ : Type u_5} {x : Option α} {g : α → Option β} {p : β → Prop} {f : (b : β) → p b → γ} (H : ∀ (a : β), a ∈ x >>= g → p a) (H' : ∀ (a : α) (b : β), b ∈ g a → b ∈ x >>= g) :
pmap f (x >>= g) H = do let a ← x pmap f (g a) ⋯
theorem Option.bind_pmap {α : Type u_5} {β γ : Type u_6} {p : α → Prop} (f : (a : α) → p a → β) (x : Option α) (g : β → Option γ) (H : ∀ (a : α), a ∈ x → p a) :
pmap f x H >>= g = x.pbind fun (a : α) (h : a ∈ x) => g (f a ⋯)
theorem Option.pbind_eq_none {α : Type u_1} {β : Type u_2} {x : Option α} {f : (a : α) → a ∈ x → Option β} (h' : ∀ (a : α) (H : a ∈ x), f a H = none → x = none) :
theorem Option.pbind_eq_some {α : Type u_1} {β : Type u_2} {x : Option α} {f : (a : α) → a ∈ x → Option β} {y : β} :
x.pbind f = some y ↔ ∃ (z : α), ∃ (H : z ∈ x), f z H = some y
theorem Option.join_pmap_eq_pmap_join {α : Type u_1} {β : Type u_2} {p : α → Prop} {f : (a : α) → p a → β} {x : Option (Option α)} (H : ∀ (a : Option α), a ∈ x → ∀ (a_2 : α), a_2 ∈ a → p a_2) :
(pmap (pmap f) x H).join = pmap f x.join ⋯
@[simp]
theorem Option.pmap_bind_id_eq_pmap_join {α : Type u_1} {β : Type u_2} {p : α → Prop} {f : (a : α) → p a → β} {x : Option (Option α)} (H : ∀ (a : Option α), a ∈ x → ∀ (a_2 : α), a_2 ∈ a → p a_2) :
((pmap (pmap f) x H).bind fun (a : Option β) => a) = pmap f x.join ⋯

simp-normal form of join_pmap_eq_pmap_join

@[simp]
theorem Option.seq_some {α β : Type u_5} {a : α} {f : α → β} :
some f <*> some a = some (f a)
@[simp]
theorem Option.some_orElse' {α : Type u_1} (a : α) (x : Option α) :
((some a).orElse fun (x_1 : Unit) => x) = some a
@[simp]
theorem Option.none_orElse' {α : Type u_1} (x : Option α) :
(none.orElse fun (x_1 : Unit) => x) = x
@[simp]
theorem Option.orElse_none' {α : Type u_1} (x : Option α) :
(x.orElse fun (x : Unit) => none) = x
theorem Option.exists_ne_none {α : Type u_1} {p : Option α → Prop} :
(∃ (x : Option α), x ≠ none ∧ p x) ↔ ∃ (x : α), p (some x)
theorem Option.iget_mem {α : Type u_1} [Inhabited α] {o : Option α} :
o.isSome = true → o.iget ∈ o
theorem Option.iget_of_mem {α : Type u_1} [Inhabited α] {a : α} {o : Option α} :
a ∈ o → o.iget = a
@[simp]
theorem Option.liftOrGet_choice {α : Type u_1} {f : α → α → α} (h : ∀ (a b : α), f a b = a ∨ f a b = b) (o₁ o₂ : Option α) :
liftOrGet f o₁ o₂ = o₁ ∨ liftOrGet f o₁ o₂ = o₂
def Option.casesOn' {α : Type u_1} {β : Type u_2} :
Option α → β → (α → β) → β

Given an element of a : Option α, a default element b : β and a function α → β, apply this function to a if it comes from α, and return b otherwise.

Equations
Instances For
    @[simp]
    theorem Option.casesOn'_none {α : Type u_1} {β : Type u_2} (x : β) (f : α → β) :
    @[simp]
    theorem Option.casesOn'_some {α : Type u_1} {β : Type u_2} (x : β) (f : α → β) (a : α) :
    (some a).casesOn' x f = f a
    @[simp]
    theorem Option.casesOn'_coe {α : Type u_1} {β : Type u_2} (x : β) (f : α → β) (a : α) :
    (some a).casesOn' x f = f a
    @[simp]
    theorem Option.casesOn'_none_coe {α : Type u_1} {β : Type u_2} (f : Option α → β) (o : Option α) :
    o.casesOn' (f none) (f ∘ fun (a : α) => some a) = f o
    theorem Option.casesOn'_eq_elim {α : Type u_1} {β : Type u_2} (b : β) (f : α → β) (a : Option α) :
    a.casesOn' b f = a.elim b f
    theorem Option.orElse_eq_some {α : Type u_1} (o o' : Option α) (x : α) :
    (o <|> o') = some x ↔ o = some x ∨ o = none ∧ o' = some x
    theorem Option.orElse_eq_some' {α : Type u_1} (o o' : Option α) (x : α) :
    (o.orElse fun (x : Unit) => o') = some x ↔ o = some x ∨ o = none ∧ o' = some x
    @[simp]
    theorem Option.orElse_eq_none {α : Type u_1} (o o' : Option α) :
    (o <|> o') = none ↔ o = none ∧ o' = none
    @[simp]
    theorem Option.orElse_eq_none' {α : Type u_1} (o o' : Option α) :
    (o.orElse fun (x : Unit) => o') = none ↔ o = none ∧ o' = none
    theorem Option.choice_eq_none (α : Type u_5) [IsEmpty α] :
    @[simp]
    theorem Option.elim_none_some {α : Type u_1} {β : Type u_2} (f : Option α → β) (i : Option α) :
    i.elim (f none) (f ∘ some) = f i
    theorem Option.elim_comp {α : Type u_1} {β : Type u_2} {γ : Type u_3} (h : α → β) {f : γ → α} {x : α} {i : Option γ} :
    (i.elim (h x) fun (j : γ) => h (f j)) = h (i.elim x f)
    theorem Option.elim_comp₂ {α : Type u_1} {β : Type u_2} {γ : Type u_3} (h : α → β → γ) {f : γ → α} {x : α} {g : γ → β} {y : β} {i : Option γ} :
    (i.elim (h x y) fun (j : γ) => h (f j) (g j)) = h (i.elim x f) (i.elim y g)
    theorem Option.elim_apply {α : Type u_1} {β : Type u_2} {γ : Type u_3} {f : γ → α → β} {x : α → β} {i : Option γ} {y : α} :
    i.elim x f y = i.elim (x y) fun (j : γ) => f j y
    @[simp]
    theorem Option.bnot_isSome {α : Type u_1} (a : Option α) :
    @[simp]
    theorem Option.bnot_comp_isSome {α : Type u_1} :
    (fun (x : Bool) => !x) ∘ isSome = isNone
    @[simp]
    theorem Option.bnot_isNone {α : Type u_1} (a : Option α) :
    @[simp]
    theorem Option.bnot_comp_isNone {α : Type u_1} :
    (fun (x : Bool) => !x) ∘ isNone = isSome
    @[simp]
    theorem Option.isNone_eq_false_iff {α : Type u_1} (a : Option α) :
    theorem Option.eq_none_or_eq_some {α : Type u_1} (a : Option α) :
    a = none ∨ ∃ (x : α), a = some x
    theorem Option.eq_none_iff_forall_some_ne {α : Type u_1} {o : Option α} :
    o = none ↔ ∀ (a : α), some a ≠ o
    @[deprecated Option.eq_none_iff_forall_some_ne (since := "2025-03-19")]
    theorem Option.forall_some_ne_iff_eq_none {α : Type u_1} {o : Option α} :
    o = none ↔ ∀ (a : α), some a ≠ o

    Alias of Option.eq_none_iff_forall_some_ne.

    @[simp]
    theorem Option.elim'_update {α : Type u_5} {β : Type u_6} [DecidableEq α] (f : β) (g : α → β) (a : α) (x : β) :