chore: remove Init.Control.Combinators
Reason: it contains a bunch of little functions that are supposed to be defined in other modules.
This commit is contained in:
parent
0d0436f1c5
commit
df8bbf5438
16 changed files with 193 additions and 138 deletions
|
|
@ -32,3 +32,11 @@ class Applicative (f : Type u → Type v) extends Functor f, HasPure f, HasSeq f
|
|||
(map := fun _ _ x y => pure x <*> y)
|
||||
(seqLeft := fun α β a b => const β <$> a <*> b)
|
||||
(seqRight := fun α β a b => const α id <$> a <*> b)
|
||||
|
||||
@[macroInline]
|
||||
def when {m : Type → Type u} [Applicative m] (c : Prop) [h : Decidable c] (t : m Unit) : m Unit :=
|
||||
if c then t else pure ()
|
||||
|
||||
@[macroInline]
|
||||
def unless {m : Type → Type u} [Applicative m] (c : Prop) [h : Decidable c] (e : m Unit) : m Unit :=
|
||||
if c then pure () else e
|
||||
|
|
|
|||
|
|
@ -1,133 +0,0 @@
|
|||
/-
|
||||
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Jeremy Avigad, Leonardo de Moura
|
||||
|
||||
Monad Combinators, as in Haskell's Control.Monad.
|
||||
-/
|
||||
prelude
|
||||
import Init.Control.Monad
|
||||
import Init.Control.Alternative
|
||||
import Init.Data.List.Basic
|
||||
|
||||
universes u v w u₁ u₂ u₃
|
||||
|
||||
def joinM {m : Type u → Type u} [Monad m] {α : Type u} (a : m (m α)) : m α :=
|
||||
bind a id
|
||||
|
||||
@[macroInline]
|
||||
def when {m : Type → Type u} [Applicative m] (c : Prop) [h : Decidable c] (t : m Unit) : m Unit :=
|
||||
if c then t else pure ()
|
||||
|
||||
@[macroInline]
|
||||
def unless {m : Type → Type u} [Applicative m] (c : Prop) [h : Decidable c] (e : m Unit) : m Unit :=
|
||||
if c then pure () else e
|
||||
|
||||
@[macroInline]
|
||||
def condM {m : Type → Type u} [Monad m] {α : Type} (mbool : m Bool) (tm fm : m α) : m α :=
|
||||
do b ← mbool; cond b tm fm
|
||||
|
||||
@[macroInline]
|
||||
def whenM {m : Type → Type u} [Monad m] (c : m Bool) (t : m Unit) : m Unit :=
|
||||
condM c t (pure ())
|
||||
|
||||
namespace Nat
|
||||
|
||||
@[specialize] def forMAux {m} [Applicative m] (f : Nat → m Unit) (n : Nat) : Nat → m Unit
|
||||
| 0 => pure ()
|
||||
| i+1 => f (n-i-1) *> forMAux i
|
||||
|
||||
@[inline] def forM {m} [Applicative m] (n : Nat) (f : Nat → m Unit) : m Unit :=
|
||||
forMAux f n n
|
||||
|
||||
@[specialize] def forRevMAux {m} [Applicative m] (f : Nat → m Unit) : Nat → m Unit
|
||||
| 0 => pure ()
|
||||
| i+1 => f i *> forRevMAux i
|
||||
|
||||
@[inline] def forRevM {m} [Applicative m] (n : Nat) (f : Nat → m Unit) : m Unit :=
|
||||
forRevMAux f n
|
||||
|
||||
@[specialize] def foldMAux {α : Type u} {m : Type u → Type v} [Monad m] (f : Nat → α → m α) (n : Nat) : Nat → α → m α
|
||||
| 0, a => pure a
|
||||
| i+1, a => f (n-i-1) a >>= foldMAux i
|
||||
|
||||
@[inline] def foldM {α : Type u} {m : Type u → Type v} [Monad m] (f : Nat → α → m α) (a : α) (n : Nat) : m α :=
|
||||
foldMAux f n n a
|
||||
|
||||
@[specialize] def foldRevMAux {α : Type u} {m : Type u → Type v} [Monad m] (f : Nat → α → m α) : Nat → α → m α
|
||||
| 0, a => pure a
|
||||
| i+1, a => f i a >>= foldRevMAux i
|
||||
|
||||
@[inline] def mfoldRev {α : Type u} {m : Type u → Type v} [Monad m] (f : Nat → α → m α) (a : α) (n : Nat) : m α :=
|
||||
foldRevMAux f n a
|
||||
|
||||
-- TODO: enable after we have support for marking arguments that should be considered for specialization.
|
||||
/-
|
||||
@[specialize]
|
||||
def mrepeat {m} [Monad m] : Nat → m Unit → m Unit
|
||||
| 0 f := pure ()
|
||||
| (k+1) f := f *> mrepeat k f
|
||||
-/
|
||||
end Nat
|
||||
|
||||
namespace List
|
||||
|
||||
@[specialize]
|
||||
def mapM {m : Type u → Type v} [Applicative m] {α : Type w} {β : Type u} (f : α → m β) : List α → m (List β)
|
||||
| [] => pure []
|
||||
| a::as => List.cons <$> (f a) <*> mapM as
|
||||
|
||||
@[specialize]
|
||||
def mapM₂ {m : Type u → Type v} [Applicative m] {α : Type u₁} {β : Type u₂} {γ : Type u} (f : α → β → m γ) : List α → List β → m (List γ)
|
||||
| a::as, b::bs => List.cons <$> (f a b) <*> mapM₂ as bs
|
||||
| _, _ => pure []
|
||||
|
||||
@[specialize]
|
||||
def forM {m : Type u → Type v} [Applicative m] {α : Type w} {β : Type u} (f : α → m β) : List α → m PUnit
|
||||
| [] => pure ⟨⟩
|
||||
| h :: t => f h *> forM t
|
||||
|
||||
@[specialize]
|
||||
def forM₂ {m : Type u → Type v} [Applicative m] {α : Type u₁} {β : Type u₂} {γ : Type u} (f : α → β → m γ) : List α → List β → m PUnit
|
||||
| a::as, b::bs => f a b *> forM₂ as bs
|
||||
| _, _ => pure ⟨⟩
|
||||
|
||||
@[specialize]
|
||||
def filterM {m : Type → Type v} [Monad m] {α : Type} (f : α → m Bool) : List α → m (List α)
|
||||
| [] => pure []
|
||||
| h :: t => do b ← f h; t' ← filterM t; cond b (pure (h :: t')) (pure t')
|
||||
|
||||
@[specialize]
|
||||
def foldlM {m : Type u → Type v} [Monad m] {s : Type u} {α : Type w} : (s → α → m s) → s → List α → m s
|
||||
| f, s, [] => pure s
|
||||
| f, s, h :: r => do
|
||||
s' ← f s h;
|
||||
foldlM f s' r
|
||||
|
||||
@[specialize]
|
||||
def foldrM {m : Type u → Type v} [Monad m] {s : Type u} {α : Type w} : (α → s → m s) → s → List α → m s
|
||||
| f, s, [] => pure s
|
||||
| f, s, h :: r => do
|
||||
s' ← foldrM f s r;
|
||||
f h s'
|
||||
|
||||
@[specialize]
|
||||
def firstM {m : Type u → Type v} [Monad m] [Alternative m] {α : Type w} {β : Type u} (f : α → m β) : List α → m β
|
||||
| [] => failure
|
||||
| a::as => f a <|> firstM as
|
||||
|
||||
@[specialize]
|
||||
def anyM {m : Type → Type u} [Monad m] {α : Type v} (f : α → m Bool) : List α → m Bool
|
||||
| [] => pure false
|
||||
| a::as => do b ← f a; match b with
|
||||
| true => pure true
|
||||
| false => anyM as
|
||||
|
||||
@[specialize]
|
||||
def allM {m : Type → Type u} [Monad m] {α : Type v} (f : α → m Bool) : List α → m Bool
|
||||
| [] => pure true
|
||||
| a::as => do b ← f a; match b with
|
||||
| true => allM as
|
||||
| false => pure false
|
||||
|
||||
end List
|
||||
|
|
@ -14,5 +14,4 @@ import Init.Control.Id
|
|||
import Init.Control.Except
|
||||
import Init.Control.Reader
|
||||
import Init.Control.Option
|
||||
import Init.Control.Combinators
|
||||
import Init.Control.Conditional
|
||||
|
|
|
|||
|
|
@ -32,3 +32,14 @@ instance monadInhabited' {α : Type u} {m : Type u → Type v} [Monad m] : Inhab
|
|||
|
||||
instance monadInhabited {α : Type u} {m : Type u → Type v} [Monad m] [Inhabited α] : Inhabited (m α) :=
|
||||
⟨pure $ default _⟩
|
||||
|
||||
def joinM {m : Type u → Type u} [Monad m] {α : Type u} (a : m (m α)) : m α :=
|
||||
bind a id
|
||||
|
||||
@[macroInline]
|
||||
def condM {m : Type → Type u} [Monad m] {α : Type} (mbool : m Bool) (tm fm : m α) : m α :=
|
||||
do b ← mbool; cond b tm fm
|
||||
|
||||
@[macroInline]
|
||||
def whenM {m : Type → Type u} [Monad m] (c : m Bool) (t : m Unit) : m Unit :=
|
||||
condM c t (pure ())
|
||||
|
|
|
|||
121
library/Init/Data/List/Control.lean
Normal file
121
library/Init/Data/List/Control.lean
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/-
|
||||
Copyright (c) 2019 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Leonardo de Moura
|
||||
-/
|
||||
prelude
|
||||
import Init.Control.Monad
|
||||
import Init.Control.Alternative
|
||||
|
||||
namespace List
|
||||
universes u v w u₁ u₂
|
||||
|
||||
/-
|
||||
Remark: we can define `mapM`, `mapM₂` and `forM` using `Applicative` instead of `Monad`.
|
||||
Example:
|
||||
```
|
||||
def mapM {m : Type u → Type v} [Applicative m] {α : Type w} {β : Type u} (f : α → m β) : List α → m (List β)
|
||||
| [] => pure []
|
||||
| a::as => List.cons <$> (f a) <*> mapM as
|
||||
```
|
||||
|
||||
However, we consider `f <$> a <*> b` an anti-idiom because the generated code
|
||||
may produce unnecessary closure allocations.
|
||||
Suppose `m` is a `Monad`, and it uses the default implementation for `Applicative.seq`.
|
||||
Then, the compiler expands `f <$> a <*> b <*> c` into something equivalent to
|
||||
```
|
||||
(Functor.map f a >>= fun g_1 => Functor.map g_1 b) >>= fun g_2 => Functor.map g_2 c
|
||||
```
|
||||
In an ideal world, the compiler may eliminate the temporary closures `g_1` and `g_2` after it inlines
|
||||
`Functor.map` and `Monad.bind`. However, this can easily fail. For example, suppose
|
||||
`Functor.map f a >>= fun g_1 => Functor.map g_1 b` expanded into a match-expression.
|
||||
This is not unreasonable and can happen in many different ways, e.g., we are using a monad that
|
||||
may throw exceptions. Then, the compiler has to decide whether it will create a join-point for
|
||||
the continuation of the match or float it. If the compiler decides to float, then it will
|
||||
be able to eliminate the closures, but it may not be feasible since floating match expressions
|
||||
may produce exponential blowup in the code size.
|
||||
|
||||
Finally, we rarely use `mapM` with something that is not a `Monad`.
|
||||
|
||||
Users that want to use `mapM` with `Applicative` should use `mapA` instead.
|
||||
-/
|
||||
|
||||
@[specialize]
|
||||
def mapM {m : Type u → Type v} [Monad m] {α : Type w} {β : Type u} (f : α → m β) : List α → m (List β)
|
||||
| [] => pure []
|
||||
| a::as => do b ← f a; bs ← mapM as; pure (b :: bs)
|
||||
|
||||
@[specialize]
|
||||
def mapM₂ {m : Type u → Type v} [Monad m] {α : Type u₁} {β : Type u₂} {γ : Type u} (f : α → β → m γ) : List α → List β → m (List γ)
|
||||
| a::as, b::bs => do c ← f a b; cs ← mapM₂ as bs; pure (c :: cs)
|
||||
| _, _ => pure []
|
||||
|
||||
@[specialize]
|
||||
def mapA {m : Type u → Type v} [Applicative m] {α : Type w} {β : Type u} (f : α → m β) : List α → m (List β)
|
||||
| [] => pure []
|
||||
| a::as => List.cons <$> f a <*> mapA as
|
||||
|
||||
@[specialize]
|
||||
def mapA₂ {m : Type u → Type v} [Applicative m] {α : Type u₁} {β : Type u₂} {γ : Type u} (f : α → β → m γ) : List α → List β → m (List γ)
|
||||
| a::as, b::bs => List.cons <$> f a b <*> mapA₂ as bs
|
||||
| _, _ => pure []
|
||||
|
||||
@[specialize]
|
||||
def forM {m : Type u → Type v} [Monad m] {α : Type w} {β : Type u} (f : α → m β) : List α → m PUnit
|
||||
| [] => pure ⟨⟩
|
||||
| h :: t => do f h; forM t
|
||||
|
||||
@[specialize]
|
||||
def forM₂ {m : Type u → Type v} [Monad m] {α : Type u₁} {β : Type u₂} {γ : Type u} (f : α → β → m γ) : List α → List β → m PUnit
|
||||
| a::as, b::bs => do f a b; forM₂ as bs
|
||||
| _, _ => pure ⟨⟩
|
||||
|
||||
@[specialize]
|
||||
def forA {m : Type u → Type v} [Applicative m] {α : Type w} {β : Type u} (f : α → m β) : List α → m PUnit
|
||||
| [] => pure ⟨⟩
|
||||
| h :: t => f h *> forA t
|
||||
|
||||
@[specialize]
|
||||
def forA₂ {m : Type u → Type v} [Applicative m] {α : Type u₁} {β : Type u₂} {γ : Type u} (f : α → β → m γ) : List α → List β → m PUnit
|
||||
| a::as, b::bs => f a b *> forA₂ as bs
|
||||
| _, _ => pure ⟨⟩
|
||||
|
||||
@[specialize]
|
||||
def filterM {m : Type → Type v} [Monad m] {α : Type} (f : α → m Bool) : List α → m (List α)
|
||||
| [] => pure []
|
||||
| h :: t => do b ← f h; t' ← filterM t; cond b (pure (h :: t')) (pure t')
|
||||
|
||||
@[specialize]
|
||||
def foldlM {m : Type u → Type v} [Monad m] {s : Type u} {α : Type w} : (s → α → m s) → s → List α → m s
|
||||
| f, s, [] => pure s
|
||||
| f, s, h :: r => do
|
||||
s' ← f s h;
|
||||
foldlM f s' r
|
||||
|
||||
@[specialize]
|
||||
def foldrM {m : Type u → Type v} [Monad m] {s : Type u} {α : Type w} : (α → s → m s) → s → List α → m s
|
||||
| f, s, [] => pure s
|
||||
| f, s, h :: r => do
|
||||
s' ← foldrM f s r;
|
||||
f h s'
|
||||
|
||||
@[specialize]
|
||||
def firstM {m : Type u → Type v} [Monad m] [Alternative m] {α : Type w} {β : Type u} (f : α → m β) : List α → m β
|
||||
| [] => failure
|
||||
| a::as => f a <|> firstM as
|
||||
|
||||
@[specialize]
|
||||
def anyM {m : Type → Type u} [Monad m] {α : Type v} (f : α → m Bool) : List α → m Bool
|
||||
| [] => pure false
|
||||
| a::as => do b ← f a; match b with
|
||||
| true => pure true
|
||||
| false => anyM as
|
||||
|
||||
@[specialize]
|
||||
def allM {m : Type → Type u} [Monad m] {α : Type v} (f : α → m Bool) : List α → m Bool
|
||||
| [] => pure true
|
||||
| a::as => do b ← f a; match b with
|
||||
| true => allM as
|
||||
| false => pure false
|
||||
|
||||
end List
|
||||
|
|
@ -7,3 +7,4 @@ prelude
|
|||
import Init.Data.List.Basic
|
||||
import Init.Data.List.BasicAux
|
||||
import Init.Data.List.Instances
|
||||
import Init.Data.List.Control
|
||||
|
|
|
|||
42
library/Init/Data/Nat/Control.lean
Normal file
42
library/Init/Data/Nat/Control.lean
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/-
|
||||
Copyright (c) 2019 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Leonardo de Moura
|
||||
-/
|
||||
prelude
|
||||
import Init.Control.Monad
|
||||
import Init.Control.Alternative
|
||||
import Init.Data.Nat.Basic
|
||||
|
||||
namespace Nat
|
||||
universes u v
|
||||
|
||||
@[specialize] def forMAux {m} [Applicative m] (f : Nat → m Unit) (n : Nat) : Nat → m Unit
|
||||
| 0 => pure ()
|
||||
| i+1 => f (n-i-1) *> forMAux i
|
||||
|
||||
@[inline] def forM {m} [Applicative m] (n : Nat) (f : Nat → m Unit) : m Unit :=
|
||||
forMAux f n n
|
||||
|
||||
@[specialize] def forRevMAux {m} [Applicative m] (f : Nat → m Unit) : Nat → m Unit
|
||||
| 0 => pure ()
|
||||
| i+1 => f i *> forRevMAux i
|
||||
|
||||
@[inline] def forRevM {m} [Applicative m] (n : Nat) (f : Nat → m Unit) : m Unit :=
|
||||
forRevMAux f n
|
||||
|
||||
@[specialize] def foldMAux {α : Type u} {m : Type u → Type v} [Monad m] (f : Nat → α → m α) (n : Nat) : Nat → α → m α
|
||||
| 0, a => pure a
|
||||
| i+1, a => f (n-i-1) a >>= foldMAux i
|
||||
|
||||
@[inline] def foldM {α : Type u} {m : Type u → Type v} [Monad m] (f : Nat → α → m α) (a : α) (n : Nat) : m α :=
|
||||
foldMAux f n n a
|
||||
|
||||
@[specialize] def foldRevMAux {α : Type u} {m : Type u → Type v} [Monad m] (f : Nat → α → m α) : Nat → α → m α
|
||||
| 0, a => pure a
|
||||
| i+1, a => f i a >>= foldRevMAux i
|
||||
|
||||
@[inline] def mfoldRev {α : Type u} {m : Type u → Type v} [Monad m] (f : Nat → α → m α) (a : α) (n : Nat) : m α :=
|
||||
foldRevMAux f n a
|
||||
|
||||
end Nat
|
||||
|
|
@ -7,3 +7,4 @@ prelude
|
|||
import Init.Data.Nat.Basic
|
||||
import Init.Data.Nat.Div
|
||||
import Init.Data.Nat.Bitwise
|
||||
import Init.Data.Nat.Control
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ prelude
|
|||
import Init.Control.Reader
|
||||
import Init.Control.Conditional
|
||||
import Init.Data.Option
|
||||
import Init.Data.List
|
||||
import Init.Lean.LocalContext
|
||||
|
||||
/-
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Leonardo de Moura
|
||||
-/
|
||||
prelude
|
||||
import Init.Data.Nat
|
||||
import Init.Lean.Compiler.ExportAttr
|
||||
import Init.Lean.Compiler.IR.CompilerM
|
||||
import Init.Lean.Compiler.IR.NormIds
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Leonardo de Moura
|
||||
-/
|
||||
prelude
|
||||
import Init.Data.AssocList
|
||||
import Init.Control.EState
|
||||
import Init.Control.Reader
|
||||
import Init.Data.AssocList
|
||||
import Init.Data.Nat
|
||||
import Init.Lean.Runtime
|
||||
import Init.Lean.Compiler.ClosedTermCache
|
||||
import Init.Lean.Compiler.ExternAttr
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ Authors: Leonardo de Moura
|
|||
prelude
|
||||
import Init.Control.Reader
|
||||
import Init.Data.Option
|
||||
import Init.Data.Nat
|
||||
import Init.Lean.Compiler.IR.Format
|
||||
import Init.Lean.Compiler.IR.Basic
|
||||
import Init.Lean.Compiler.IR.CompilerM
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ Authors: Leonardo de Moura
|
|||
prelude
|
||||
import Init.Control.State
|
||||
import Init.Control.Reader
|
||||
import Init.Data.Nat
|
||||
import Init.Lean.Compiler.IR.CompilerM
|
||||
import Init.Lean.Compiler.IR.NormIds
|
||||
import Init.Lean.Compiler.IR.FreeVars
|
||||
|
|
|
|||
|
|
@ -4,10 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Sebastian Ullrich and Leonardo de Moura
|
||||
-/
|
||||
prelude
|
||||
import Init.Lean.KVMap
|
||||
import Init.System.IO
|
||||
import Init.Control.Combinators
|
||||
import Init.Data.ToString
|
||||
import Init.Lean.KVMap
|
||||
|
||||
namespace Lean
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ prelude
|
|||
import Init.System.IO
|
||||
import Init.System.FilePath
|
||||
import Init.Data.Array
|
||||
import Init.Control.Combinators
|
||||
import Init.Data.List.Control
|
||||
import Init.Lean.Name
|
||||
|
||||
namespace Lean
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ Custom unifier for tabled typeclass resolution.
|
|||
Note: this file will be removed once the unifier is implemented in Lean.
|
||||
-/
|
||||
prelude
|
||||
import Init.Data.Nat
|
||||
import Init.Data.PersistentArray
|
||||
import Init.Lean.Expr
|
||||
import Init.Lean.MetavarContext
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue