refactor(library): revise the monadic hierarchy

This commit is contained in:
Sebastian Ullrich 2017-03-08 17:44:57 +01:00 committed by Leonardo de Moura
parent b0a33259ee
commit 763097dbd2
27 changed files with 103 additions and 161 deletions

View file

@ -8,16 +8,16 @@ import init.logic init.category.applicative
universes u v
class alternative (f : Type u → Type v) extends applicative f : Type (max u+1 v) :=
(failure : Π {a : Type u}, f a)
(orelse : Π {a : Type u}, f a → f a → f a)
(failure : Π {α : Type u}, f α)
(orelse : Π {α : Type u}, f α → f α → f α)
section
variables {f : Type u → Type v} [alternative f] {a : Type u}
variables {f : Type u → Type v} [alternative f] {α : Type u}
@[inline] def failure : f a :=
@[inline] def failure : f α :=
alternative.failure f
@[inline] def orelse : f a → f a → f a :=
@[inline] def orelse : f α → f α → f α :=
alternative.orelse
infixr ` <|> `:2 := orelse
@ -31,7 +31,7 @@ if p then pure () else failure
| tt := pure ()
| ff := failure
@[inline] def optional (x : f a) : f (option a) :=
@[inline] def optional (x : f α) : f (option α) :=
some <$> x <|> pure none
end

View file

@ -1,38 +1,38 @@
/-
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
Authors: Leonardo de Moura, Sebastian Ullrich
-/
prelude
import init.category.functor
import init.function
open function
universes u v
class applicative (f : Type u → Type v) extends functor f : Type (max u+1 v):=
(pure : Π {a : Type u}, a → f a)
(seq : Π {a b : Type u}, f (a → b) → f a → f b)
class applicative (f : Type u → Type v) extends functor f :=
(pure : Π {α : Type u}, α → f α)
(seq : Π {α β : Type u}, f (α → β) → f α → f β)
(seq_left : Π {α β : Type u}, f α → f β → f α := λ α β a b, seq (map (const β) a) b)
(seq_right : Π {α β : Type u}, f α → f β → f β := λ α β a b, seq (map (const α id) a) b)
(map := λ _ _ x y, seq (pure x) y)
section
variables {a b : Type u} {f : Type u → Type v} [applicative f]
variables {f : Type u → Type v} [applicative f] {α β : Type u}
@[inline] def pure : a → f a :=
@[inline] def pure : α → f α :=
applicative.pure f
@[inline] def seq_app : f (a → b) → f a → f b :=
@[inline] def seq_app : f (α → β) → f α → f β :=
applicative.seq
infixl ` <*> `:2 := seq_app
/-- Sequence actions, discarding the first value. -/
def seq_left (x : f a) (y : f b) : f a :=
pure (λ x y, x) <*> x <*> y
@[inline] def seq_left : f α → f β → f α :=
applicative.seq_left
/-- Sequence actions, discarding the second value. -/
def seq_right (x : f a) (y : f b) : f b :=
pure (λ x y, y) <*> x <*> y
infixl ` <* `:2 := seq_left
infixl ` *> `:2 := seq_right
@[inline] def seq_right : f α → f β → f β :=
applicative.seq_right
infixl ` <*> `:2 := seq_app
infixl ` <* `:2 := seq_left
infixl ` *> `:2 := seq_right
end

View file

@ -1,16 +1,23 @@
/-
Copyright (c) Luke Nelson and Jared Roesch. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Luke Nelson and Jared Roesch
Authors: Luke Nelson, Jared Roesch, Sebastian Ullrich
-/
prelude
import init.core
import init.core init.function
open function
universes u v
class functor (f : Type u → Type v) : Type (max u+1 v) :=
(map : Π {a b : Type u}, (a → b) → f a → f b)
(map : Π {α β : Type u}, (α → β) → f α → f β)
(map_const : Π {α : Type u} (β : Type u), α → f β → f α := λ α β, map ∘ const β)
@[inline] def fmap {f : Type u → Type v} [functor f] {a b : Type u} : (a → b) → f a → f b :=
@[inline] def fmap {f : Type u → Type v} [functor f] {α β : Type u} : (α → β) → f α → f β :=
functor.map
@[inline] def fmap_const {f : Type u → Type v} [functor f] {α : Type u} : Π (β : Type u), α → f β → f α :=
functor.map_const
infixr ` <$> `:100 := fmap
infixr ` <$ `:100 := fmap_const
infixr ` $> `:100 := λ α a b, fmap_const α b a

View file

@ -1,38 +1,32 @@
/-
Copyright (c) Luke Nelson and Jared Roesch. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Luke Nelson and Jared Roesch
Authors: Leonardo de Moura, Luke Nelson, Jared Roesch, Sebastian Ullrich
-/
prelude
import init.category.applicative
universes u v
class pre_monad (m : Type u → Type v) :=
(bind : Π {a b : Type u}, m a → (a → m b) → m b)
(bind : Π {α β : Type u}, m α → (α → m β) → m β)
@[inline] def bind {m : Type u → Type v} [pre_monad m] {a b : Type u} : m a → (a → m b) → m b :=
@[inline] def bind {m : Type u → Type v} [pre_monad m] {α β : Type u} : m α → (α → m β) → m β :=
pre_monad.bind
@[inline] def pre_monad.and_then {a b : Type u} {m : Type u → Type v} [pre_monad m] (x : m a) (y : m b) : m b :=
@[inline] def pre_monad.and_then {α β : Type u} {m : Type u → Type v} [pre_monad m] (x : m α) (y : m β) : m β :=
do x, y
class monad (m : Type u → Type v) extends functor m, pre_monad m : Type (max u+1 v) :=
(ret : Π {a : Type u}, a → m a)
@[inline] def return {m : Type u → Type v} [monad m] {a : Type u} : a → m a :=
monad.ret m
def fapp {m : Type u → Type v} [monad m] {a b : Type u} (f : m (a → b)) (a : m a) : m b :=
do g ← f,
b ← a,
return (g b)
@[inline] instance monad_is_applicative (m : Type u → Type v) [monad m] : applicative m :=
⟨@fmap _ _, @return _ _, @fapp _ _⟩
infixl ` >>= `:2 := bind
infixl ` >> `:2 := pre_monad.and_then
class monad (m : Type u → Type v) extends applicative m, pre_monad m : Type (max u+1 v) :=
(seq := λ α β f x, bind f $ λ f, bind x $ λ x, pure (f x))
-- implied by `seq`, but a bit simpler
(map := λ α β f x, bind x $ λ x, pure (f x))
def return {m : Type u → Type v} [monad m] {α : Type u} : α → m α :=
pure
/- Identical to pre_monad.and_then, but it is not inlined. -/
def pre_monad.seq {a b : Type u} {m : Type u → Type v} [pre_monad m] (x : m a) (y : m b) : m b :=
def pre_monad.seq {α β : Type u} {m : Type u → Type v} [pre_monad m] (x : m α) (y : m β) : m β :=
do x, y

View file

@ -12,9 +12,6 @@ def state (σ : Type) (α : Type) : Type :=
section
variables {σ : Type} {α β : Type}
@[inline] def state_fmap (f : α → β) (a : state σ α) : state σ β :=
λ s, match (a s) with (a', s') := (f a', s') end
@[inline] def state_return (a : α) : state σ α :=
λ s, (a, s)
@ -22,9 +19,7 @@ variables {σ : Type} {α β : Type}
λ s, match (a s) with (a', s') := b a' s' end
instance (σ : Type) : monad (state σ) :=
{ map := @state_fmap σ,
ret := @state_return σ,
bind := @state_bind σ }
{pure := @state_return σ, bind := @state_bind σ}
end
namespace state
@ -44,11 +39,6 @@ section
variable [monad m]
variables {α β : Type}
def state_t_fmap (f : α → β) (act : state_t σ m α) : state_t σ m β :=
λ s, show m (β × σ), from
do (a, new_s) ← act s,
return (f a, new_s)
def state_t_return (a : α) : state_t σ m α :=
λ s, show m (α × σ), from
return (a, s)
@ -60,9 +50,7 @@ section
end
instance (σ : Type) (m : Type → Type) [monad m] : monad (state_t σ m) :=
{ map := @state_t_fmap σ m _,
ret := @state_t_return σ m _,
bind := @state_t_bind σ m _}
{pure := @state_t_return σ m _, bind := @state_t_bind σ m _}
section
variable {σ : Type}
@ -79,9 +67,7 @@ section
end
instance (σ : Type) (m : Type → Type) [alternative m] [monad m] : alternative (state_t σ m) :=
{ map := @state_t_fmap σ m _,
pure := @state_t_return σ m _,
seq := @fapp _ _,
{ state_t.monad σ m with
failure := @state_t_failure σ m _ _,
orelse := @state_t_orelse σ m _ _ }

View file

@ -229,4 +229,4 @@ join (map b a)
end list
instance : monad list :=
{map := @list.map, ret := @list.ret, bind := @list.bind}
{map := @list.map, pure := @list.ret, bind := @list.bind}

View file

@ -11,7 +11,9 @@ open list
universes u v
instance : alternative list :=
⟨@map, @list.ret, @fapp _ _, @nil, @list.append⟩
{ list.monad with
failure := @nil,
orelse := @list.append }
instance {α : Type u} [decidable_eq α] : decidable_eq (list α) :=
by tactic.mk_dec_eq_instance

View file

@ -53,16 +53,12 @@ instance {α : Type u} [d : decidable_eq α] : decidable_eq (option α)
| (is_false n) := is_false (λ h, option.no_confusion h (λ e, absurd e n))
end
@[inline] def option_fmap {α : Type u} {β : Type v} (f : α → β) : option α → option β
| none := none
| (some a) := some (f a)
@[inline] def option_bind {α : Type u} {β : Type v} : option α → (α → option β) → option β
| none b := none
| (some a) b := b a
instance : monad option :=
{map := @option_fmap, ret := @some, bind := @option_bind}
{pure := @some, bind := @option_bind}
def option_orelse {α : Type u} : option α → option α → option α
| (some a) o := some a
@ -70,19 +66,13 @@ def option_orelse {α : Type u} : option α → option α → option α
| none none := none
instance : alternative option :=
alternative.mk @option_fmap @some (@fapp _ _) @none @option_orelse
{ option.monad with
failure := @none,
orelse := @option_orelse }
def option_t (m : Type u → Type v) [monad m] (α : Type u) : Type v :=
m (option α)
@[inline] def option_t_fmap {m : Type u → Type v} [monad m] {α β : Type u} (f : α → β) (e : option_t m α) : option_t m β :=
show m (option β), from
do o ← e,
match o with
| none := return none
| (some a) := return (some (f a))
end
@[inline] def option_t_bind {m : Type u → Type v} [monad m] {α β : Type u} (a : option_t m α) (b : α → option_t m β)
: option_t m β :=
show m (option β), from
@ -97,7 +87,7 @@ show m (option α), from
return (some a)
instance {m : Type u → Type v} [monad m] : monad (option_t m) :=
{map := @option_t_fmap m _, ret := @option_t_return m _, bind := @option_t_bind m _}
{pure := @option_t_return m _, bind := @option_t_bind m _}
def option_t_orelse {m : Type u → Type v} [monad m] {α : Type u} (a : option_t m α) (b : option_t m α) : option_t m α :=
show m (option α), from
@ -112,11 +102,9 @@ show m (option α), from
return none
instance {m : Type u → Type v} [monad m] : alternative (option_t m) :=
{map := @option_t_fmap m _,
pure := @option_t_return m _,
seq := @fapp (option_t m) (@option_t.monad m _),
failure := @option_t_fail m _,
orelse := @option_t_orelse m _}
{ option_t.monad with
failure := @option_t_fail m _,
orelse := @option_t_orelse m _ }
def option_t.lift {m : Type u → Type v} [monad m] {α : Type u} (a : m α) : option_t m α :=
(some <$> a : m (option α))

View file

@ -74,6 +74,6 @@ def image (f : α → β) (s : set α) : set β :=
{b | ∃ a, a ∈ s ∧ f a = b}
instance : functor set :=
⟨@set.image⟩
{map := @set.image}
end set

View file

@ -69,13 +69,11 @@ protected meta def bind {α β : Type} (c₁ : conv α) (c₂ : α → conv β)
meta instance : monad conv :=
{ map := @conv.map,
ret := @conv.pure,
pure := @conv.pure,
bind := @conv.bind }
meta instance : alternative conv :=
{ map := @conv.map,
pure := @conv.pure,
seq := @conv.seq,
{ conv.monad with
failure := @conv.fail,
orelse := @conv.orelse }

View file

@ -37,11 +37,6 @@ protected meta def to_option : exceptional α → option α
| (success a) := some a
| (exception .α _) := none
@[inline] protected meta def fmap (f : α → β) (e : exceptional α) : exceptional β :=
exceptional.cases_on e
(λ a, success (f a))
(λ f, exception β f)
@[inline] protected meta def bind (e₁ : exceptional α) (e₂ : α → exceptional β) : exceptional β :=
exceptional.cases_on e₁
(λ a, e₂ a)
@ -55,4 +50,4 @@ exception α (λ u, f)
end exceptional
meta instance : monad exceptional :=
{map := @exceptional.fmap, ret := @exceptional.return, bind := @exceptional.bind}
{pure := @exceptional.return, bind := @exceptional.bind}

View file

@ -63,7 +63,7 @@ meta def interaction_monad_orelse {α : Type u} (t₁ t₂ : m α) : m α :=
interaction_monad_bind t₁ (λ a, t₂)
meta instance interaction_monad.monad : monad m :=
{map := @interaction_monad_fmap, ret := @interaction_monad_return, bind := @interaction_monad_bind}
{map := @interaction_monad_fmap, pure := @interaction_monad_return, bind := @interaction_monad_bind}
meta def interaction_monad.mk_exception {α : Type u} {β : Type v} [has_to_format β] (msg : β) (ref : option expr) (s : state) : result state α :=
exception (some (λ _, to_fmt msg)) none s

View file

@ -47,7 +47,9 @@ result.cases_on (p₁ s)
exception)
meta instance : alternative parser :=
⟨@interaction_monad_fmap parser_state, (λ α a s, success a s), (@fapp _ _), @interaction_monad.failed parser_state, @parser_orelse⟩
{ interaction_monad.monad with
failure := @interaction_monad.failed _,
orelse := @parser_orelse }
-- TODO: move

View file

@ -82,11 +82,9 @@ meta instance : monad_fail smt_tactic :=
{ smt_tactic.monad with fail := λ α s, (tactic.fail (to_fmt s) : smt_tactic α) }
meta instance : alternative smt_tactic :=
{failure := λ α, @tactic.failed α,
orelse := @smt_tactic_orelse,
pure := @return _ _,
seq := @fapp _ _,
map := @fmap _ _}
{ smt_tactic.monad with
failure := λ α, @tactic.failed α,
orelse := @smt_tactic_orelse }
namespace smt_tactic
open tactic (transparency)

View file

@ -51,7 +51,9 @@ infixl ` >>=[tactic] `:2 := interaction_monad_bind
infixl ` >>[tactic] `:2 := interaction_monad_seq
meta instance : alternative tactic :=
⟨@interaction_monad_fmap tactic_state, (λ α a s, success a s), (@fapp _ _), @interaction_monad.failed tactic_state, @interaction_monad_orelse tactic_state⟩
{ interaction_monad.monad with
failure := @interaction_monad.failed _,
orelse := @interaction_monad_orelse _ }
meta def {u₁ u₂} tactic.up {α : Type u₂} (t : tactic α) : tactic (ulift.{u₁} α) :=
λ s, match t s with

View file

@ -14,7 +14,7 @@ protected meta def {u v} bind {α : Type u} {β : Type v} (t : task α) (f : α
task.flatten (task.map f t)
meta instance : monad task :=
{ map := @task.map, bind := @task.bind, ret := @task.pure }
{ map := @task.map, bind := @task.bind, pure := @task.pure }
@[inline]
meta def {u} delay {α : Type u} (f : unit → α) : task α :=

View file

@ -77,7 +77,7 @@ meta constant vm_core.ret {α : Type} : α → vm_core α
meta constant vm_core.bind {α β : Type} : vm_core α → (α → vm_core β) → vm_core β
meta instance : monad vm_core :=
{map := @vm_core.map, ret := @vm_core.ret, bind := @vm_core.bind}
{map := @vm_core.map, pure := @vm_core.ret, bind := @vm_core.bind}
@[reducible] meta def vm (α : Type) : Type := option_t vm_core α

View file

@ -5,11 +5,7 @@ Authors: Jared Roesch
-/
prelude
import init.category.applicative
import init.category.functor
import init.category.monad
import init.logic
import init.function
namespace native
@ -21,24 +17,12 @@ def unwrap_or {E T : Type} : result E T → T → T
| (result.err _) default := default
| (result.ok t) _ := t
def result.map : Π {E : Type} {T : Type} {U : Type}, (T → U) → result E T → result E U
| E T U f (result.err e) := result.err e
| E T U f (result.ok t) := result.ok (f t)
def result.and_then {E T U : Type} : result E T → (T → result E U) → result E U
| (result.err e) _ := result.err e
| (result.ok t) f := f t
instance result_functor (E : Type) : functor (result E) := functor.mk (@result.map E)
def result.seq {E T U : Type} : result E (T → U) → result E T → result E U
| f t := result.and_then f (fun f', result.and_then t (fun t', result.ok (f' t')))
instance result_applicative (E : Type) : applicative (result E) :=
applicative.mk (@result.map E) (@result.ok E) (@result.seq E)
instance result_monad (E : Type) : monad (result E) :=
{map := @result.map E, ret := @result.ok E, bind := @result.and_then E}
{pure := @result.ok E, bind := @result.and_then E}
inductive resultT (M : Type → Type) (E : Type) (A : Type) : Type
| run : M (result E A) → resultT
@ -46,9 +30,6 @@ inductive resultT (M : Type → Type) (E : Type) (A : Type) : Type
section resultT
variable {M : Type → Type}
def resultT.map [functor : functor M] {E : Type} {A B : Type} : (A → B) → resultT M E A → resultT M E B
| f (resultT.run action) := resultT.run (@functor.map M functor _ _ (result.map f) action)
def resultT.pure [monad : monad M] {E A : Type} (x : A) : resultT M E A :=
resultT.run $ return (result.ok x)
@ -56,17 +37,13 @@ section resultT
| (resultT.run action) f := resultT.run (do
res_a ← action,
-- a little ugly with this match
(match res_a with
| native.result.err e := return (native.result.err e)
| native.result.ok a := let (resultT.run actionB) := f a in actionB
end : M (result E B)))
match res_a with
| result.err e := return (result.err e)
| result.ok a := let (resultT.run actionB) := f a in actionB
end)
instance resultT_functor [f : functor M] (E : Type) : functor (resultT M E) :=
functor.mk (@resultT.map M f E)
-- Should we unify functor and monad like haskell?
instance resultT_monad [f : functor M] [m : monad M] (E : Type) : monad (resultT M E) :=
{map := @resultT.map M f E, ret := @resultT.pure M m E, bind := @resultT.and_then M m E}
instance resultT_monad [m : monad M] (E : Type) : monad (resultT M E) :=
{pure := @resultT.pure M m E, bind := @resultT.and_then M m E}
end resultT
end native

View file

@ -12,7 +12,7 @@ constant io.put_str : string → io unit
constant io.get_line : io string
instance : monad io :=
{ ret := @io.return,
{ pure := @io.return,
bind := @io.bind,
map := @io.map }

View file

@ -154,7 +154,7 @@ meta def orelse (A : Type) (p1 p2 : prover A) : prover A :=
take state, p1 state <|> p2 state
meta instance : alternative prover :=
{ monad_is_applicative prover with
{ prover.monad with
failure := λα, fail "failed",
orelse := orelse }

View file

@ -365,12 +365,12 @@ class erase_irrelevant_fn : public compiler_step_visitor {
}
}
expr visit_monad_return(expr const & e, buffer<expr> const & args) {
expr visit_applicative_pure(expr const & e, buffer<expr> const & args) {
if (args.size() == 4 && is_builtin_state_monad(args[1])) {
/* IO monad return
return v := fun s, (v, s)
Remark: we do not return the state explicility.
Remark: we do not return the state explicitly.
*/
expr u = mk_neutral_expr();
expr s = mk_var(0);
@ -420,8 +420,8 @@ class erase_irrelevant_fn : public compiler_step_visitor {
return visit_subtype_rec(args);
} else if (n == get_monad_bind_name() || n == get_pre_monad_bind_name()) {
return visit_monad_bind(e, args);
} else if (n == get_monad_ret_name()) {
return visit_monad_return(e, args);
} else if (n == get_applicative_pure_name()) {
return visit_applicative_pure(e, args);
} else if (is_cases_on_recursor(env(), n)) {
return visit_cases_on(fn, args);
} else if (inductive::is_elim_rule(env(), n)) {

View file

@ -16,6 +16,7 @@ name const * g_and_elim_left = nullptr;
name const * g_and_elim_right = nullptr;
name const * g_and_intro = nullptr;
name const * g_andthen = nullptr;
name const * g_applicative_pure = nullptr;
name const * g_auto_param = nullptr;
name const * g_bit0 = nullptr;
name const * g_bit1 = nullptr;
@ -176,7 +177,6 @@ name const * g_match_failed = nullptr;
name const * g_mod = nullptr;
name const * g_monad = nullptr;
name const * g_monad_bind = nullptr;
name const * g_monad_ret = nullptr;
name const * g_monad_fail = nullptr;
name const * g_monoid = nullptr;
name const * g_mul = nullptr;
@ -391,6 +391,7 @@ void initialize_constants() {
g_and_elim_right = new name{"and", "elim_right"};
g_and_intro = new name{"and", "intro"};
g_andthen = new name{"andthen"};
g_applicative_pure = new name{"applicative", "pure"};
g_auto_param = new name{"auto_param"};
g_bit0 = new name{"bit0"};
g_bit1 = new name{"bit1"};
@ -551,7 +552,6 @@ void initialize_constants() {
g_mod = new name{"mod"};
g_monad = new name{"monad"};
g_monad_bind = new name{"monad", "bind"};
g_monad_ret = new name{"monad", "ret"};
g_monad_fail = new name{"monad_fail"};
g_monoid = new name{"monoid"};
g_mul = new name{"mul"};
@ -767,6 +767,7 @@ void finalize_constants() {
delete g_and_elim_right;
delete g_and_intro;
delete g_andthen;
delete g_applicative_pure;
delete g_auto_param;
delete g_bit0;
delete g_bit1;
@ -927,7 +928,6 @@ void finalize_constants() {
delete g_mod;
delete g_monad;
delete g_monad_bind;
delete g_monad_ret;
delete g_monad_fail;
delete g_monoid;
delete g_mul;
@ -1142,6 +1142,7 @@ name const & get_and_elim_left_name() { return *g_and_elim_left; }
name const & get_and_elim_right_name() { return *g_and_elim_right; }
name const & get_and_intro_name() { return *g_and_intro; }
name const & get_andthen_name() { return *g_andthen; }
name const & get_applicative_pure_name() { return *g_applicative_pure; }
name const & get_auto_param_name() { return *g_auto_param; }
name const & get_bit0_name() { return *g_bit0; }
name const & get_bit1_name() { return *g_bit1; }
@ -1302,7 +1303,6 @@ name const & get_match_failed_name() { return *g_match_failed; }
name const & get_mod_name() { return *g_mod; }
name const & get_monad_name() { return *g_monad; }
name const & get_monad_bind_name() { return *g_monad_bind; }
name const & get_monad_ret_name() { return *g_monad_ret; }
name const & get_monad_fail_name() { return *g_monad_fail; }
name const & get_monoid_name() { return *g_monoid; }
name const & get_mul_name() { return *g_mul; }

View file

@ -18,6 +18,7 @@ name const & get_and_elim_left_name();
name const & get_and_elim_right_name();
name const & get_and_intro_name();
name const & get_andthen_name();
name const & get_applicative_pure_name();
name const & get_auto_param_name();
name const & get_bit0_name();
name const & get_bit1_name();
@ -178,7 +179,6 @@ name const & get_match_failed_name();
name const & get_mod_name();
name const & get_monad_name();
name const & get_monad_bind_name();
name const & get_monad_ret_name();
name const & get_monad_fail_name();
name const & get_monoid_name();
name const & get_mul_name();

View file

@ -11,6 +11,7 @@ and.elim_left
and.elim_right
and.intro
andthen
applicative.pure
auto_param
bit0
bit1
@ -171,7 +172,6 @@ match_failed
mod
monad
monad.bind
monad.ret
monad_fail
monoid
mul

View file

@ -16,6 +16,7 @@ run_cmd script_check_id `and.elim_left
run_cmd script_check_id `and.elim_right
run_cmd script_check_id `and.intro
run_cmd script_check_id `andthen
run_cmd script_check_id `applicative.pure
run_cmd script_check_id `auto_param
run_cmd script_check_id `bit0
run_cmd script_check_id `bit1
@ -176,7 +177,6 @@ run_cmd script_check_id `match_failed
run_cmd script_check_id `mod
run_cmd script_check_id `monad
run_cmd script_check_id `monad.bind
run_cmd script_check_id `monad.ret
run_cmd script_check_id `monad_fail
run_cmd script_check_id `monoid
run_cmd script_check_id `mul

View file

@ -23,9 +23,6 @@ meta instance {α : Type} : has_coe (tactic α) (lazy_tactic α) :=
protected meta def return {α} (a : α) : lazy_tactic α :=
λ s, lazy_list.singleton (a, s)
protected meta def map {α β} (f : α → β) : lazy_tactic α → lazy_tactic β
| t s := (t s)^.for (λ ⟨a, new_s⟩, (f a, new_s))
protected meta def bind {α β} : lazy_tactic α → (α → lazy_tactic β) → lazy_tactic β :=
λ t₁ t₂ s, join (for (t₁ s) (λ ⟨a, new_s⟩, t₂ a new_s))
@ -36,17 +33,13 @@ protected meta def failure {α} : lazy_tactic α :=
λ s, nil
meta instance : monad lazy_tactic :=
{ ret := @lazy_tactic.return,
bind := @lazy_tactic.bind,
map := @lazy_tactic.map }
{ pure := @lazy_tactic.return,
bind := @lazy_tactic.bind }
meta instance : alternative lazy_tactic :=
{ map := @lazy_tactic.map,
pure := @lazy_tactic.return,
seq := @fapp _ _,
{ lazy_tactic.monad with
failure := @lazy_tactic.failure,
orelse := @lazy_tactic.orelse
}
orelse := @lazy_tactic.orelse }
meta def choose {α} (xs : list α) : lazy_tactic α :=
λ s, of_list $ xs^.for (λ a, (a, s))

View file

@ -1,6 +1,6 @@
type_error_at_eval_expr.lean:3:0: error: eval_expr failed due to type error
nested exception message:
type mismatch at definition '_eval_expr.16.423', has type
type mismatch at definition '_eval_expr.16.436', has type
list
but is expected to have type