feat(library/init/data/array/basic): add new array functions
@kha I renamed the homogeneous `map` to `hmap`, and added the heterogeneous one as `map`. As soon as we add user-defined rewriting rules, we will be able to replace `map` with `hmap` whenever the types are the same.
This commit is contained in:
parent
0c9fe3c7d4
commit
4d3689ea33
3 changed files with 35 additions and 3 deletions
|
|
@ -124,6 +124,26 @@ miterateAux a f 0 b
|
|||
|
||||
@[inline] def mfoldl (a : Array α) (b : β) (f : α → β → m β) : m β :=
|
||||
miterate a b (λ _, f)
|
||||
|
||||
@[inline] def mfoldlFrom (a : Array α) (b : β) (f : α → β → m β) (ini : Nat := 0) : m β :=
|
||||
miterateAux a (λ _, f) ini b
|
||||
|
||||
local attribute [instance] monadInhabited
|
||||
|
||||
-- TODO(Leo): justify termination using wf-rec
|
||||
@[specialize] partial def mfindAux (a : Array α) (f : α → m (Option β)) : Nat → m (Option β)
|
||||
| i :=
|
||||
if h : i < a.sz then
|
||||
let idx : Fin a.sz := ⟨i, h⟩ in
|
||||
do r ← f (a.index idx),
|
||||
(match r with
|
||||
| some v := pure r
|
||||
| none := mfindAux (i+1))
|
||||
else pure none
|
||||
|
||||
@[inline] def mfind (a : Array α) (f : α → m (Option β)) : m (Option β) :=
|
||||
mfindAux a f 0
|
||||
|
||||
end
|
||||
|
||||
@[inline] def iterate (a : Array α) (b : β) (f : Π i : Fin a.sz, α → β → β) : β :=
|
||||
|
|
@ -132,6 +152,12 @@ Id.run $ miterateAux a f 0 b
|
|||
@[inline] def foldl (a : Array α) (f : α → β → β) (b : β) : β :=
|
||||
iterate a b (λ _, f)
|
||||
|
||||
@[inline] def foldlFrom (a : Array α) (f : α → β → β) (b : β) (ini : Nat := 0) : β :=
|
||||
Id.run $ mfoldlFrom a b f ini
|
||||
|
||||
@[inline] def find (a : Array α) (f : α → Option β) : Option β :=
|
||||
Id.run $ mfindAux a f 0
|
||||
|
||||
@[specialize] private def revIterateAux (a : Array α) (f : Π i : Fin a.sz, α → β → β) : Π (i : Nat), i ≤ a.sz → β → β
|
||||
| 0 h b := b
|
||||
| (j+1) h b :=
|
||||
|
|
@ -175,14 +201,18 @@ Id.run $ mforeach a f
|
|||
theorem szForeachEq (a : Array α) (f : Π i : Fin a.sz, α → α) : (foreach a f).sz = a.sz :=
|
||||
(Id.run $ mforeachAux a f).property
|
||||
|
||||
@[inline] def map (f : α → α) (a : Array α) : Array α :=
|
||||
/- Homogeneous map -/
|
||||
@[inline] def hmap (f : α → α) (a : Array α) : Array α :=
|
||||
foreach a (λ _, f)
|
||||
|
||||
@[inline] def map₂ (f : α → α → α) (a b : Array α) : Array α :=
|
||||
@[inline] def hmap₂ (f : α → α → α) (a b : Array α) : Array α :=
|
||||
if h : a.size ≤ b.size
|
||||
then foreach a (λ ⟨i, h'⟩, f (b.index ⟨i, Nat.ltOfLtOfLe h' h⟩))
|
||||
else foreach b (λ ⟨i, h'⟩, f (a.index ⟨i, Nat.ltTrans h' (Nat.gtOfNotLe h)⟩))
|
||||
|
||||
def map (f : α → β) (as : Array α) : Array β :=
|
||||
as.foldl (λ a bs, bs.push (f a)) (mkEmpty as.sz)
|
||||
|
||||
end Array
|
||||
|
||||
export Array (mkArray)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ do
|
|||
IO.println (toString a.sz),
|
||||
let a := foo a,
|
||||
IO.println (toString a),
|
||||
let a := a.map (+10),
|
||||
let a := a.hmap (+10),
|
||||
IO.println (toString a),
|
||||
IO.println (toString a.sz),
|
||||
let a1 := a.pop,
|
||||
|
|
@ -21,4 +21,5 @@ do
|
|||
IO.println (toString a2),
|
||||
let a2 := a.pop,
|
||||
IO.println a2,
|
||||
IO.println $ (([1, 2, 3, 4].toArray).hmap (+2)).map toString,
|
||||
pure 0
|
||||
|
|
|
|||
|
|
@ -6,3 +6,4 @@
|
|||
[10, 11, 12]
|
||||
[10, 11, 12, 13, 100]
|
||||
[10, 11, 12]
|
||||
[3, 4, 5, 6]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue