@@ -1692,6 +1692,40 @@ def getMax? (as : Array α) (lt : α → α → Bool) : Option α :=
16921692 else
16931693 none
16941694
1695+ /-! ### partitionM -/
1696+
1697+ /--
1698+ Returns a pair of arrays that together contain all the elements of `as`. The first array contains
1699+ those elements for which the monadic predicate `p` returns `true`, and the second contains those for
1700+ which `p` returns `false`. The array's elements are examined in order, from left to right.
1701+
1702+ This is a monadic version of `Array.partition`.
1703+
1704+ Example:
1705+ ```lean
1706+ def posOrNeg (x : Int) : Except String Bool :=
1707+ if x > 0 then pure true
1708+ else if x < 0 then pure false
1709+ else throw "Zero is not positive or negative"
1710+
1711+ #eval #[-1, 2, 3].partitionM posOrNeg
1712+ -- Except.ok (#[2, 3], #[-1])
1713+
1714+ #eval #[0, 2, 3].partitionM posOrNeg
1715+ -- Except.error "Zero is not positive or negative"
1716+ ```
1717+ -/
1718+ @[inline, specialize]
1719+ def partitionM {α : Type } [Monad m] (p : α → m Bool) (as : Array α) : m (Array α × Array α) := do
1720+ let mut bs := #[]
1721+ let mut cs := #[]
1722+ for a in as do
1723+ if (← p a) then
1724+ bs := bs.push a
1725+ else
1726+ cs := cs.push a
1727+ return (bs, cs)
1728+
16951729/--
16961730Returns a pair of arrays that together contain all the elements of `as`. The first array contains
16971731those elements for which `p` returns `true`, and the second contains those for which `p` returns
@@ -1716,6 +1750,46 @@ def partition (p : α → Bool) (as : Array α) : Array α × Array α := Id.run
17161750 cs := cs.push a
17171751 return (bs, cs)
17181752
1753+ /-! ### partitionMapM -/
1754+
1755+ /--
1756+ Applies a monadic function that returns a disjoint union to each element of an array,
1757+ collecting the `Sum.inl` and `Sum.inr` results into separate arrays.
1758+
1759+ Example:
1760+ ```lean
1761+ def f (x : Int) : Except String (Int ⊕ String) :=
1762+ if x % 2 = 0 then pure (Sum.inl x)
1763+ else pure (Sum.inr (toString x))
1764+
1765+ #eval #[0, 1, 2, 3].partitionMapM f
1766+ -- Except.ok (#[0, 2], #["1", "3"])
1767+ ```
1768+ -/
1769+ @[inline, specialize]
1770+ def partitionMapM [Monad m] (f : α → m (β ⊕ γ)) (as : Array α) : m (Array β × Array γ) := do
1771+ let mut bs := #[]
1772+ let mut cs := #[]
1773+ for a in as do
1774+ match ← f a with
1775+ | Sum.inl b => bs := bs.push b
1776+ | Sum.inr c => cs := cs.push c
1777+ return (bs, cs)
1778+
1779+ /-! ### partitionMap -/
1780+
1781+ /--
1782+ Applies a function that returns a disjoint union to each element of an array, collecting the `Sum.inl`
1783+ and `Sum.inr` results into separate arrays.
1784+
1785+ Examples:
1786+ * `#[0, 1, 2, 3].partitionMap (fun x => if x % 2 = 0 then .inl x else .inr x) = (#[0, 2], #[1, 3])`
1787+ * `#[0, 1, 2, 3].partitionMap (fun x => if x = 0 then .inl x else .inr x) = (#[0], #[1, 2, 3])`
1788+ -/
1789+ @[inline]
1790+ def partitionMap (f : α → β ⊕ γ) (as : Array α) : Array β × Array γ :=
1791+ Id.run <| partitionMapM (fun a => pure (f a)) as
1792+
17191793/--
17201794Removes all the elements that satisfy a predicate from the end of an array.
17211795
0 commit comments