feat(library/init/data/array/basic): new Array operations from syntax-array experiment
This commit is contained in:
parent
a86b852d1c
commit
c8e11d289f
2 changed files with 51 additions and 15 deletions
|
|
@ -22,7 +22,12 @@ class Monad (m : Type u → Type v) extends Applicative m, HasBind m : Type (max
|
|||
(seqLeft := λ α β x y, x >>= λ a, y >>= λ _, pure a)
|
||||
(seqRight := λ α β x y, x >>= λ _, y)
|
||||
|
||||
/- We do not add this instance by default because it is rarely needed,
|
||||
and it could slow down the current type class resolution procedure. -/
|
||||
|
||||
/- We do not add these instances by default because they are rarely needed,
|
||||
and could slow down the current type class resolution procedure. -/
|
||||
|
||||
def monadInhabited {α : Type u} {m : Type u → Type v} [Monad m] [Inhabited α] : Inhabited (m α) :=
|
||||
⟨pure $ default _⟩
|
||||
|
||||
def monadInhabited' {α : Type u} {m : Type u → Type v} [Monad m] : Inhabited (α → m α) :=
|
||||
⟨pure⟩
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Authors: Leonardo de Moura
|
|||
-/
|
||||
prelude
|
||||
import init.data.nat.basic init.data.fin.basic init.data.uint
|
||||
import init.data.repr init.data.tostring
|
||||
import init.data.repr init.data.tostring init.control.id
|
||||
universes u v w
|
||||
|
||||
/-
|
||||
|
|
@ -46,9 +46,15 @@ mkEmpty ()
|
|||
instance : HasEmptyc (Array α) :=
|
||||
⟨Array.empty⟩
|
||||
|
||||
instance : Inhabited (Array α) :=
|
||||
⟨Array.empty⟩
|
||||
|
||||
def isEmpty (a : Array α) : Bool :=
|
||||
a.size = 0
|
||||
|
||||
def singleton (v : α) : Array α :=
|
||||
mkArray 1 v
|
||||
|
||||
@[extern cpp inline "lean::array_index(#2, #3)"]
|
||||
def index (a : @& Array α) (i : @& Fin a.sz) : α :=
|
||||
a.data i
|
||||
|
|
@ -65,6 +71,9 @@ a.index ⟨i.toNat, h⟩
|
|||
def get [Inhabited α] (a : @& Array α) (i : @& Nat) : α :=
|
||||
if h : i < a.sz then a.index ⟨i, h⟩ else default α
|
||||
|
||||
def getOpt (a : Array α) (i : Nat) : Option α :=
|
||||
if h : i < a.size then some (a.index ⟨i, h⟩) else none
|
||||
|
||||
@[extern cpp inline "lean::array_update(#2, #3, #4)"]
|
||||
def update (a : Array α) (i : @& Fin a.sz) (v : α) : Array α :=
|
||||
{ sz := a.sz,
|
||||
|
|
@ -97,16 +106,27 @@ def pop (a : Array α) : Array α :=
|
|||
{ sz := Nat.pred a.sz,
|
||||
data := λ ⟨j, h⟩, a.index ⟨j, Nat.ltOfLtOfLe h (Nat.predLe _)⟩ }
|
||||
|
||||
section
|
||||
variables {m : Type v → Type v} [Monad m]
|
||||
local attribute [instance] monadInhabited'
|
||||
|
||||
-- TODO(Leo): justify termination using wf-rec
|
||||
@[specialize] partial def iterateAux (a : Array α) (f : Π i : Fin a.sz, α → β → β) : Nat → β → β
|
||||
@[specialize] partial def miterateAux (a : Array α) (f : Π i : Fin a.sz, α → β → m β) : Nat → β → m β
|
||||
| i b :=
|
||||
if h : i < a.sz then
|
||||
let idx : Fin a.sz := ⟨i, h⟩ in
|
||||
iterateAux (i+1) (f idx (a.index idx) b)
|
||||
else b
|
||||
f idx (a.index idx) b >>= miterateAux (i+1)
|
||||
else pure b
|
||||
|
||||
@[inline] def miterate (a : Array α) (b : β) (f : Π i : Fin a.sz, α → β → m β) : m β :=
|
||||
miterateAux a f 0 b
|
||||
|
||||
@[inline] def mfoldl (a : Array α) (b : β) (f : α → β → m β) : m β :=
|
||||
miterate a b (λ _, f)
|
||||
end
|
||||
|
||||
@[inline] def iterate (a : Array α) (b : β) (f : Π i : Fin a.sz, α → β → β) : β :=
|
||||
iterateAux a f 0 b
|
||||
id.run $ miterateAux a f 0 b
|
||||
|
||||
@[inline] def foldl (a : Array α) (f : α → β → β) (b : β) : β :=
|
||||
iterate a b (λ _, f)
|
||||
|
|
@ -132,16 +152,27 @@ instance [HasRepr α] : HasRepr (Array α) :=
|
|||
instance [HasToString α] : HasToString (Array α) :=
|
||||
⟨toString ∘ toList⟩
|
||||
|
||||
@[inline] private def foreachAux (a : Array α) (f : Π i : Fin a.sz, α → α) : { a' : Array α // a'.sz = a.sz } :=
|
||||
iterate a ⟨a, rfl⟩ $ λ i v ⟨a', h⟩,
|
||||
let i' : Fin a'.sz := Eq.recOn h.symm i in
|
||||
⟨a'.update i' (f i v), (szUpdateEq a' i' (f i v)) ▸ h⟩
|
||||
section
|
||||
variables {m : Type u → Type u} [Monad m]
|
||||
|
||||
@[inline] private def mforeachAux (a : Array α) (f : Π i : Fin a.sz, α → m α) : m { a' : Array α // a'.sz = a.sz } :=
|
||||
miterate a ⟨a, rfl⟩ $ λ i v ⟨a', h⟩, do
|
||||
let i' : Fin a'.sz := Eq.recOn h.symm i,
|
||||
x ← f i v,
|
||||
pure $ ⟨a'.update i' x, (szUpdateEq a' i' x) ▸ h⟩
|
||||
|
||||
@[inline] def mforeach (a : Array α) (f : Π i : Fin a.sz, α → m α) : m (Array α) :=
|
||||
Subtype.val <$> mforeachAux a f
|
||||
|
||||
@[inline] def mmap (f : α → m α) (a : Array α) : m (Array α) :=
|
||||
mforeach a (λ _, f)
|
||||
end
|
||||
|
||||
@[inline] def foreach (a : Array α) (f : Π i : Fin a.sz, α → α) : Array α :=
|
||||
(foreachAux a f).val
|
||||
id.run $ mforeach a f
|
||||
|
||||
theorem szForeachEq (a : Array α) (f : Π i : Fin a.sz, α → α) : (foreach a f).sz = a.sz :=
|
||||
(foreachAux a f).property
|
||||
(id.run $ mforeachAux a f).property
|
||||
|
||||
@[inline] def map (f : α → α) (a : Array α) : Array α :=
|
||||
foreach a (λ _, f)
|
||||
|
|
@ -153,9 +184,9 @@ else foreach b (λ ⟨i, h'⟩, f (a.index ⟨i, Nat.ltTrans h' (Nat.gtOfNotLe h
|
|||
|
||||
end Array
|
||||
|
||||
def List.toArrayAux {α : Type u} : List α → Array α → Array α
|
||||
@[inlineIfReduce] def List.toArrayAux {α : Type u} : List α → Array α → Array α
|
||||
| [] r := r
|
||||
| (a::as) r := List.toArrayAux as (r.push a)
|
||||
|
||||
def List.toArray {α : Type u} (l : List α) : Array α :=
|
||||
@[inline] def List.toArray {α : Type u} (l : List α) : Array α :=
|
||||
l.toArrayAux ∅
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue