lean4-htt/library/init/category/monad.lean
Leonardo de Moura d34386fef7 perf(frontends/lean/tactic_notation): closes #1345
We can now elaborate
https://gist.github.com/gebner/439273deee592603190d4f8b4447295b
in 1.6 secs and using less than 500Kb of stack space.
It was takins 44 secs and 5Mb before this commit.

Two modifications:
1) Use pre_monad.seq instead of pre_monad.and_then.
They have the same implementation, but seq is not marked as [inline].

2) Modify how we concatenate the tactics in a begin...end block.
Before: (((a_1 ++ a_2) ++ a_3) ++ a_4)
After:  ((a_1 ++ a_2) ++ (a_3 ++ a_4))
2017-01-30 14:13:53 -08:00

38 lines
1.3 KiB
Text

/-
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
-/
prelude
import init.category.applicative
universe variables u v
class pre_monad (m : Type u → Type v) :=
(bind : Π {a b : Type u}, m a → (a → m b) → m b)
@[inline] def bind {m : Type u → Type v} [pre_monad m] {a b : Type u} : m a → (a → m b) → m b :=
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 :=
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
/- 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 :=
do x, y