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:
- It is the prototype of addition of terms to a type. See for example
with_bot α
which usesnone
as an element smaller than all others. - It can be used to define failsafe partial functions, which return
some the_result_we_expect
if we can findthe_result_we_expect
, andnone
if there is no meaningful result. This forces any subsequent use of the partial function to explicitly deal with the exceptions that make it returnnone
. option
is a monad. We love monads.
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
.
Implementation notes #
option
is currently defined in core Lean, but this will change in Lean 4.
@[simp]
theorem
option.get_of_mem
{α : Type u_1}
{a : α}
{o : option α}
(h : ↥(o.is_some)) :
a ∈ o → option.get h = a
@[simp]
@[simp]
@[simp]
theorem
option.get_or_else_of_ne_none
{α : Type u_1}
{x : option α}
(hx : x ≠ none)
(y : α) :
some (x.get_or_else y) = x
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]
@[simp]
@[simp]
theorem
option.map_some'
{α : Type u_1}
{β : Type u_2}
{a : α}
{f : α → β} :
option.map f (some a) = some (f a)
@[simp]
theorem
option.map_congr
{α : Type u_1}
{β : Type u_2}
{f g : α → β}
{x : option α}
(h : ∀ (a : α), a ∈ x → f a = g a) :
option.map f x = option.map g x
@[simp]
theorem
option.map_map
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
(h : β → γ)
(g : α → β)
(x : option α) :
option.map h (option.map g x) = option.map (h ∘ g) x
theorem
option.comp_map
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
(h : β → γ)
(g : α → β)
(x : option α) :
option.map (h ∘ g) x = option.map h (option.map g x)
@[simp]
theorem
option.map_comp_map
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
(f : α → β)
(g : β → γ) :
option.map g ∘ option.map f = option.map (g ∘ f)
theorem
option.mem_map_of_mem
{α : Type u_1}
{β : Type u_2}
{a : α}
{x : option α}
(g : α → β)
(h : a ∈ x) :
g a ∈ option.map g x
theorem
option.bind_map_comm
{α β : Type u_1}
{x : option (option α)}
{f : α → β} :
x >>= option.map f = option.map (option.map f) x >>= id
theorem
option.join_map_eq_map_join
{α : Type u_1}
{β : Type u_2}
{f : α → β}
{x : option (option α)} :
(option.map (option.map f) x).join = option.map f x.join
theorem
option.join_join
{α : Type u_1}
{x : option (option (option α))} :
x.join.join = (option.map option.join x).join
theorem
option.map_bind
{α β γ : Type u_1}
(f : β → γ)
(x : option α)
(g : α → option β) :
option.map f (x >>= g) = x >>= λ (a : α), option.map f (g a)
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 (λ (a : α), option.map f (g a))
theorem
option.map_pbind
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
(f : β → γ)
(x : option α)
(g : Π (a : α), a ∈ x → option β) :
option.map f (x.pbind g) = x.pbind (λ (a : α) (H : a ∈ x), option.map f (g a H))
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 (λ (a : α) (h : a ∈ x), g (f a) _)
@[simp]
theorem
option.pmap_none
{α : Type u_1}
{β : Type u_2}
{p : α → Prop}
(f : Π (a : α), p a → β)
{H : ∀ (a : α), a ∈ none → p a} :
option.pmap f none H = none
@[simp]
theorem
option.pmap_some
{α : Type u_1}
{β : Type u_2}
{p : α → Prop}
(f : Π (a : α), p a → β)
{x : α}
(h : p x) :
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 _ ∈ option.pmap f x h
theorem
option.pmap_map
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
{p : α → Prop}
(f : Π (a : α), p a → β)
(g : γ → α)
(x : option γ)
(H : ∀ (a : α), a ∈ option.map g x → p a) :
option.pmap f (option.map g x) H = option.pmap (λ (a : γ) (h : p (g a)), f (g a) h) x _
theorem
option.map_pmap
{α : Type u_1}
{β : Type u_2}
{γ : Type u_3}
{p : α → Prop}
(g : β → γ)
(f : Π (a : α), p a → β)
(x : option α)
(H : ∀ (a : α), a ∈ x → p a) :
option.map g (option.pmap f x H) = option.pmap (λ (a : α) (h : p a), g (f a h)) x H
@[simp]
theorem
option.pmap_eq_map
{α : Type u_1}
{β : Type u_2}
(p : α → Prop)
(f : α → β)
(x : option α)
(H : ∀ (a : α), a ∈ x → p a) :
option.pmap (λ (a : α) (_x : p a), f a) x H = option.map f x
theorem
option.pmap_bind
{α β γ : Type u_1}
{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) :
option.pmap f (x >>= g) H = x >>= λ (a : α), option.pmap f (g a) _
theorem
option.bind_pmap
{α : Type u_1}
{β γ : Type u_2}
{p : α → Prop}
(f : Π (a : α), p a → β)
(x : option α)
(g : β → option γ)
(H : ∀ (a : α), a ∈ x → p a) :
option.pmap f x H >>= g = x.pbind (λ (a : α) (h : a ∈ x), g (f a _))
@[simp]
theorem
option.pmap_eq_none_iff
{α : Type u_1}
{β : Type u_2}
{p : α → Prop}
{f : Π (a : α), p a → β}
{x : option α}
{h : ∀ (a : α), a ∈ x → p a} :
@[simp]
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_1 : α), a_1 ∈ a → p a_1) :
(option.pmap (option.pmap f) x H).join = option.pmap f x.join _
@[simp]
theorem
option.lift_or_get_choice
{α : Type u_1}
{f : α → α → α}
(h : ∀ (a b : α), f a b = a ∨ f a b = b)
(o₁ o₂ : option α) :
option.lift_or_get f o₁ o₂ = o₁ ∨ option.lift_or_get f o₁ o₂ = o₂
@[simp]
theorem
option.lift_or_get_none_left
{α : Type u_1}
{f : α → α → α}
{b : option α} :
option.lift_or_get f none b = b
@[simp]
theorem
option.lift_or_get_none_right
{α : Type u_1}
{f : α → α → α}
{a : option α} :
option.lift_or_get f a none = a
@[simp]
theorem
option.lift_or_get_some_some
{α : Type u_1}
{f : α → α → α}
{a b : α} :
option.lift_or_get f (some a) (some b) = ↑(f a b)
@[simp]
@[simp]
@[simp]
@[simp]
theorem
option.get_or_else_map
{α : Type u_1}
{β : Type u_2}
(f : α → β)
(x : α)
(o : option α) :
(option.map f o).get_or_else (f x) = f (o.get_or_else x)
theorem
option.choice_is_some_iff_nonempty
{α : Type u_1} :
↥((option.choice α).is_some) ↔ nonempty α