refactor: Foldable => Traversable
This commit is contained in:
parent
9234145955
commit
35e1f5ad97
3 changed files with 26 additions and 27 deletions
|
|
@ -7,14 +7,13 @@ prelude
|
|||
import Init.Core
|
||||
|
||||
/-
|
||||
Typeclass for the polymorphic `foldlM` operation described in the paper.
|
||||
Typeclass for the polymorphic `forM` operation described in the "do unchained" paper.
|
||||
Remark:
|
||||
- `γ` is a "container" type of elements of type `α`.
|
||||
- `α` is treated as an output parameter by the typeclass resolution procedure.
|
||||
That is, it tries to find an instance using only `m` and `γ`.
|
||||
-/
|
||||
class Foldable (m : Type u → Type v) (γ : Type w₁) (α : outParam (Type w₂)) where
|
||||
foldlM [Monad m] : (δ → α → m δ) → δ → γ → m δ
|
||||
class Traversable (m : Type u → Type v) (γ : Type w₁) (α : outParam (Type w₂)) where
|
||||
forM [Monad m] : γ → (α → m PUnit) → m PUnit
|
||||
|
||||
-- Add the alias `foldlM` for `Foldable.foldlM`
|
||||
export Foldable (foldlM)
|
||||
export Traversable (forM)
|
||||
|
|
@ -5,7 +5,7 @@ Author: Leonardo de Moura
|
|||
-/
|
||||
prelude
|
||||
import Init.Control.Basic
|
||||
import Init.Control.Foldable
|
||||
import Init.Control.Traversable
|
||||
import Init.Data.List.Basic
|
||||
|
||||
namespace List
|
||||
|
|
@ -52,14 +52,16 @@ def mapA {m : Type u → Type v} [Applicative m] {α : Type w} {β : Type u} (f
|
|||
| a::as => List.cons <$> f a <*> mapA f as
|
||||
|
||||
@[specialize]
|
||||
def forM {m : Type u → Type v} [Monad m] {α : Type w} (f : α → m PUnit) : List α → m PUnit
|
||||
| [] => pure ⟨⟩
|
||||
| h :: t => do f h; forM f t
|
||||
protected def forM {m : Type u → Type v} [Monad m] {α : Type w} (as : List α) (f : α → m PUnit) : m PUnit :=
|
||||
match as with
|
||||
| [] => pure ⟨⟩
|
||||
| a :: as => do f a; List.forM as f
|
||||
|
||||
@[specialize]
|
||||
def forA {m : Type u → Type v} [Applicative m] {α : Type w} (f : α → m PUnit) : List α → m PUnit
|
||||
| [] => pure ⟨⟩
|
||||
| h :: t => f h *> forA f t
|
||||
def forA {m : Type u → Type v} [Applicative m] {α : Type w} (as : List α) (f : α → m PUnit) : m PUnit :=
|
||||
match as with
|
||||
| [] => pure ⟨⟩
|
||||
| a :: as => f a *> forA as f
|
||||
|
||||
@[specialize]
|
||||
def filterAuxM {m : Type → Type v} [Monad m] {α : Type} (f : α → m Bool) : List α → List α → m (List α)
|
||||
|
|
@ -150,14 +152,12 @@ def findSomeM? {m : Type u → Type v} [Monad m] {α : Type w} {β : Type u} (f
|
|||
instance : ForIn m (List α) α where
|
||||
forIn := List.forIn
|
||||
|
||||
instance : Foldable m (List α) α where
|
||||
foldlM := List.foldlM
|
||||
instance : Traversable m (List α) α where
|
||||
forM := List.forM
|
||||
|
||||
-- Add two simplification lemmas for `foldlM` over lists
|
||||
@[simp] theorem foldlM_nil [Monad m] (f : δ → α → m δ) (d : δ) : foldlM f d ([] : List α) = pure d :=
|
||||
@[simp] theorem forM_nil [Monad m] (f : α → m PUnit) : forM [] f = pure ⟨⟩ :=
|
||||
rfl
|
||||
|
||||
@[simp] theorem foldlM_cons [Monad m] (f : δ → α → m δ) (d : δ) (a : α) (as : List α) : foldlM f d (a::as) = f d a >>= fun d => foldlM f d as :=
|
||||
@[simp] theorem forM_cons [Monad m] (f : α → m PUnit) (a : α) (as : List α) : forM (a::as) f = f a >>= fun _ => forM as f :=
|
||||
rfl
|
||||
|
||||
end List
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Authors: Leonardo de Moura
|
|||
-/
|
||||
prelude
|
||||
import Init.Meta
|
||||
import Init.Control.Foldable
|
||||
import Init.Control.Traversable
|
||||
|
||||
namespace Std
|
||||
-- We put `Range` in `Init` because we want the notation `[i:j]` without importing `Std`
|
||||
|
|
@ -32,17 +32,17 @@ universes u v
|
|||
instance : ForIn m Range Nat where
|
||||
forIn := Range.forIn
|
||||
|
||||
@[inline] protected def foldlM {β : Type u} {m : Type u → Type v} [Monad m] (f : β → Nat → m β) (init : β) (range : Range) : m β :=
|
||||
let rec @[specialize] loop (i : Nat) (j : Nat) (b : β) : m β := do
|
||||
@[inline] protected def forM {m : Type u → Type v} [Monad m] (range : Range) (f : Nat → m PUnit) : m PUnit :=
|
||||
let rec @[specialize] loop (i : Nat) (j : Nat) : m PUnit := do
|
||||
if j ≥ range.stop then
|
||||
pure b
|
||||
pure ⟨⟩
|
||||
else match i with
|
||||
| 0 => pure b
|
||||
| i+1 => loop i (j + range.step) (← f b j)
|
||||
loop range.stop range.start init
|
||||
| 0 => pure ⟨⟩
|
||||
| i+1 => f j; loop i (j + range.step)
|
||||
loop range.stop range.start
|
||||
|
||||
instance : Foldable m Range Nat where
|
||||
foldlM := Range.foldlM
|
||||
instance : Traversable m Range Nat where
|
||||
forM := Range.forM
|
||||
|
||||
syntax:max "[" ":" term "]" : term
|
||||
syntax:max "[" term ":" term "]" : term
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue