fix(library/init): alternative instances

Both `alternative` and `monad` implement `applicative`. However,
their default implementations for `seq_right` and `seq_left` are
different. The `alternative` implementation uses the inefficient default
version for `seq_right` available at `applicative`:
```
(seq_right := λ α β a b, const α id <$> a <*> b)
```
instead of the more efficient
```
(seq_right := λ α β x y, x >>= λ _, y)
```
defined at `monad` using the `bind` operator.

This commit makes sure the `applicative` instances for `reader_t`,
`state_t`, `option` and `parsec_t` use the efficient version.
I found the problem when inspecting the generated code for:
```
def symbol (s : string) : parsec' unit :=
(str s *> whitespace) <?> ("'" ++ s ++ "'")
```
This commit is contained in:
Leonardo de Moura 2018-10-17 14:25:50 -07:00
parent 17cb9b4532
commit 38bc3beffb
4 changed files with 9 additions and 5 deletions

View file

@ -59,7 +59,8 @@ section
instance [alternative m] : alternative (reader_t ρ m) :=
{ failure := @reader_t.failure _ _ _ _,
orelse := @reader_t.orelse _ _ _ _ }
orelse := @reader_t.orelse _ _ _ _,
..reader_t.monad }
instance (ε) [monad m] [monad_except ε m] : monad_except ε (reader_t ρ m) :=
{ throw := λ α, reader_t.lift ∘ throw,

View file

@ -43,7 +43,8 @@ section
instance [alternative m] : alternative (state_t σ m) :=
{ failure := @state_t.failure _ _ _ _,
orelse := @state_t.orelse _ _ _ _ }
orelse := @state_t.orelse _ _ _ _,
..state_t.monad }
@[inline] protected def get : state_t σ m σ :=
λ s, pure (s, s)

View file

@ -55,7 +55,8 @@ protected def orelse {α : Type u} : option α → option α → option α
instance : alternative option :=
{ failure := @none,
orelse := @option.orelse }
orelse := @option.orelse,
..option.monad }
protected def lt {α : Type u} (r : αα → Prop) : option α → option α → Prop
| none (some x) := true

View file

@ -201,8 +201,9 @@ match r with
| other := pure other
instance [inhabited μ] : alternative (parsec_t μ m) :=
{ orelse := λ _, parsec_t.orelse,
failure := λ _, parsec_t.failure }
{ orelse := λ _, parsec_t.orelse,
failure := λ _, parsec_t.failure,
..parsec_t.monad }
/-- Parse `p` without consuming any input. -/
def lookahead (p : parsec_t μ m α) : parsec_t μ m α :=