/- Copyright (c) 2014 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura -/ prelude import init.logic init.monad init.alternative open decidable universe variables u v attribute [instance] definition option_is_inhabited (A : Type u) : inhabited (option A) := ⟨none⟩ attribute [instance] definition option_has_decidable_eq {A : Type u} [H : decidable_eq A] : ∀ o₁ o₂ : option A, decidable (o₁ = o₂) | none none := is_true rfl | none (some v₂) := is_false (λ H, option.no_confusion H) | (some v₁) none := is_false (λ H, option.no_confusion H) | (some v₁) (some v₂) := match (H v₁ v₂) with | (is_true e) := is_true (congr_arg (@some A) e) | (is_false n) := is_false (λ H, option.no_confusion H (λ e, absurd e n)) end attribute [inline] definition option_fmap {A : Type u} {B : Type v} (f : A → B) : option A → option B | none := none | (some a) := some (f a) attribute [inline] definition option_bind {A : Type u} {B : Type v} : option A → (A → option B) → option B | none b := none | (some a) b := b a attribute [instance] definition option_is_monad : monad option := monad.mk @option_fmap @some @option_bind definition option_orelse {A : Type u} : option A → option A → option A | (some a) o := some a | none (some a) := some a | none none := none attribute [instance] definition option_is_alternative {A : Type u} : alternative option := alternative.mk @option_fmap @some (@fapp _ _) @none @option_orelse definition optionT (M : Type (max 1 u) → Type v) [monad M] (A : Type u) : Type v := M (option A) attribute [inline] definition optionT_fmap {M : Type (max 1 u) → Type v} [monad M] {A B : Type u} (f : A → B) (e : optionT M A) : optionT M B := show M (option B), from do o ← e, match o with | none := return none | (some a) := return (some (f a)) end attribute [inline] definition optionT_bind {M : Type (max 1 u) → Type v} [monad M] {A B : Type u} (a : optionT M A) (b : A → optionT M B) : optionT M B := show M (option B), from do o ← a, match o with | none := return none | (some a) := b a end attribute [inline] definition optionT_return {M : Type (max 1 u) → Type v} [monad M] {A : Type u} (a : A) : optionT M A := show M (option A), from return (some a) attribute [instance] definition optionT_is_monad {M : Type (max 1 u) → Type v} [monad M] {A : Type u} : monad (optionT M) := monad.mk (@optionT_fmap M _) (@optionT_return M _) (@optionT_bind M _) definition optionT_orelse {M : Type (max 1 u) → Type v} [monad M] {A : Type u} (a : optionT M A) (b : optionT M A) : optionT M A := show M (option A), from do o ← a, match o with | none := b | (some v) := return (some v) end definition optionT_fail {M : Type (max 1 u) → Type v} [monad M] {A : Type u} : optionT M A := show M (option A), from return none attribute [instance] definition optionT_is_alternative {M : Type (max 1 u) → Type v} [monad M] {A : Type u} : alternative (optionT M) := alternative.mk (@optionT_fmap M _) (@optionT_return M _) (@fapp (optionT M) (@optionT_is_monad M _ A)) (@optionT_fail M _) (@optionT_orelse M _)