feat(init/category): misc enhancements from the tactic refactoring
This commit is contained in:
parent
4742d44a74
commit
5599c9ca67
3 changed files with 48 additions and 8 deletions
|
|
@ -5,10 +5,10 @@ Authors: Jared Roesch, Sebastian Ullrich
|
|||
-/
|
||||
|
||||
prelude
|
||||
import init.category.transformers
|
||||
import init.category.alternative init.category.transformers
|
||||
universes u v w
|
||||
|
||||
inductive except (ε α : Type u)
|
||||
inductive except (ε : Type u) (α : Type v)
|
||||
| error {} : ε → except
|
||||
| ok {} : α → except
|
||||
|
||||
|
|
@ -16,24 +16,51 @@ class monad_except (ε : out_param (Type u)) (m : Type v → Type w) :=
|
|||
(throw {} {α : Type v} : ε → m α)
|
||||
(catch {} {α : Type v} : m α → (ε → m α) → m α)
|
||||
|
||||
namespace monad_except
|
||||
variables {ε : Type u} {m : Type v → Type w}
|
||||
|
||||
protected def orelse [monad_except ε m] {α : Type v} (t₁ t₂ : m α) : m α :=
|
||||
catch t₁ $ λ _, t₂
|
||||
|
||||
/- Alternative orelse operator that allows to select which exception should be used.
|
||||
The default is to use the first exception since the standard `orelse` uses the second. -/
|
||||
meta def orelse' [monad_except ε m] {α : Type v} (t₁ t₂ : m α) (use_first_ex := tt) : m α :=
|
||||
catch t₁ $ λ e₁, catch t₂ $ λ e₂, throw (if use_first_ex then e₁ else e₂)
|
||||
end monad_except
|
||||
|
||||
export monad_except (throw catch)
|
||||
|
||||
namespace except
|
||||
section
|
||||
parameter {ε : Type u}
|
||||
|
||||
protected def return {α : Type u} (a : α) : except ε α :=
|
||||
protected def return {α : Type v} (a : α) : except ε α :=
|
||||
except.ok a
|
||||
|
||||
protected def map {α β : Type u} (f : α → β) : except ε α → except ε β
|
||||
protected def map {α β : Type v} (f : α → β) : except ε α → except ε β
|
||||
| (except.error err) := except.error err
|
||||
| (except.ok v) := except.ok $ f v
|
||||
|
||||
protected def bind {α β : Type u} (ma : except ε α) (f : α → except ε β) : except ε β :=
|
||||
protected def map_error {ε' : Type u} {α : Type v} (f : ε → ε') : except ε α → except ε' α
|
||||
| (except.error err) := except.error $ f err
|
||||
| (except.ok v) := except.ok v
|
||||
|
||||
protected def bind {α β : Type v} (ma : except ε α) (f : α → except ε β) : except ε β :=
|
||||
match ma with
|
||||
| (except.error err) := except.error err
|
||||
| (except.ok v) := f v
|
||||
end
|
||||
|
||||
protected def to_bool {α : Type v} : except ε α → bool
|
||||
| (except.ok _) := tt
|
||||
| (except.error _) := ff
|
||||
|
||||
protected def to_option {α : Type v} : except ε α → option α
|
||||
| (except.ok a) := some a
|
||||
| (except.error _) := none
|
||||
|
||||
instance : monad (except ε) :=
|
||||
{ pure := @return, bind := @bind }
|
||||
end
|
||||
end except
|
||||
|
||||
|
|
@ -59,6 +86,9 @@ section
|
|||
protected def lift {α : Type u} (t : m α) : except_t ε m α :=
|
||||
⟨except.ok <$> t⟩
|
||||
|
||||
instance : has_monad_lift m (except_t ε m) :=
|
||||
⟨@except_t.lift⟩
|
||||
|
||||
protected def catch {α : Type u} (ma : except_t ε m α) (handle : ε → except_t ε m α) : except_t ε m α :=
|
||||
⟨ma.run >>= λ res, match res with
|
||||
| except.ok a := pure (except.ok a)
|
||||
|
|
|
|||
|
|
@ -4,12 +4,19 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Leonardo de Moura
|
||||
-/
|
||||
prelude
|
||||
import init.category.monad init.data.string.basic
|
||||
import init.category.transformers init.data.string.basic
|
||||
|
||||
universes u v
|
||||
|
||||
class monad_fail (m : Type u → Type v) extends monad m :=
|
||||
(fail : Π {a}, string → m a)
|
||||
|
||||
-- deriving monad from monad_fail should happen only as a last resort
|
||||
attribute [instance, priority 1] monad_fail.to_monad
|
||||
|
||||
def match_failed {α : Type u} {m : Type u → Type v} [monad_fail m] : m α :=
|
||||
monad_fail.fail m "match failed"
|
||||
|
||||
-- TODO(Sebastian): Could take `has_monad_lift_t`, except that the refl instances will make it loop
|
||||
instance monad_fail_lift (m n : Type u → Type v) [has_monad_lift m n] [monad_fail m] [monad_n : monad n] : monad_fail n :=
|
||||
{ fail := λ α s, monad_lift (monad_fail.fail m s : m α), ..monad_n }
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ section
|
|||
variable [monad m]
|
||||
variables {α β : Type u}
|
||||
|
||||
protected def run (st : σ) (x : state_t σ m α) : m (α × σ) :=
|
||||
@[inline] protected def run (st : σ) (x : state_t σ m α) : m (α × σ) :=
|
||||
state_t.run' x st
|
||||
|
||||
protected def pure (a : α) : state_t σ m α :=
|
||||
|
|
@ -56,7 +56,7 @@ section
|
|||
protected def lift {α : Type u} (t : m α) : state_t σ m α :=
|
||||
⟨λ s, do a ← t, return (a, s)⟩
|
||||
|
||||
instance has_monad_lift_lift (m) [monad m] : has_monad_lift m (state_t σ m) :=
|
||||
instance (m) [monad m] : has_monad_lift m (state_t σ m) :=
|
||||
⟨@state_t.lift σ m _⟩
|
||||
|
||||
protected def map {σ m m'} [monad m] [monad m'] {α} (f : Π {α}, m α → m' α) : state_t σ m α → state_t σ m' α :=
|
||||
|
|
@ -90,6 +90,9 @@ variables {σ : Type u} {m : Type u → Type v} {n : Type u → Type w} [monad m
|
|||
@[inline] def get : n σ :=
|
||||
@monad_lift _ _ _ _ (state_t.get : state_t σ m _)
|
||||
|
||||
@[inline] def get_type (σ : Type u) [has_monad_lift_t (state_t σ m) n] : n σ :=
|
||||
get
|
||||
|
||||
@[inline] def put (st : σ) : n punit :=
|
||||
monad_lift (state_t.put st : state_t σ m _)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue