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 usesnoneas an element smaller than all others.
- It can be used to define failsafe partial functions, which return some the_result_we_expectif we can findthe_result_we_expect, andnoneif there is no meaningful result. This forces any subsequent use of the partial function to explicitly deal with the exceptions that make it returnnone.
- optionis 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
@[simp]
    
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_coe'
    {α : Type u_1}
    {β : Type u_2}
    {a : α}
    {f : α → β} :
option.map f ↑a = ↑(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 α
Functions from option can be combined similarly to vector.cons.
Equations
- option.cons a f = λ (o : option α), o.elim a f
@[simp]
    
theorem
option.cons_none_some
    {α : Type u_1}
    {β : Type u_2}
    (f : option α → β) :
option.cons (f none) (f ∘ some) = f