feat: HashSet.all/any (#5582)

I think the overhead (runtime/later proving) of using `for` is paid off
by being able to short-circuit.

These functions are needed downstream to switch over the Std.HashSet.
This commit is contained in:
Kim Morrison 2024-10-02 14:23:27 +10:00 committed by GitHub
parent 478a34f174
commit 1329a264c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 28 additions and 0 deletions

View file

@ -195,6 +195,18 @@ instance [BEq α] [Hashable α] {m : Type v → Type v} : ForM m (HashSet α) α
instance [BEq α] [Hashable α] {m : Type v → Type v} : ForIn m (HashSet α) α where
forIn m init f := m.forIn f init
/-- Check if all elements satisfy the predicate, short-circuiting if a predicate fails. -/
@[inline] def all (m : HashSet α) (p : α → Bool) : Bool := Id.run do
for a in m do
if ¬ p a then return false
return true
/-- Check if any element satisfies the predicate, short-circuiting if a predicate succeeds. -/
@[inline] def any (m : HashSet α) (p : α → Bool) : Bool := Id.run do
for a in m do
if p a then return true
return false
/-- Transforms the hash set into a list of elements in some order. -/
@[inline] def toList (m : HashSet α) : List α :=
m.inner.keys

View file

@ -428,6 +428,22 @@ def addKeyToState (k : Nat) : StateM Nat PUnit := do
ans := k :: ans
return ans
/-- info: true -/
#guard_msgs in
#eval m.any fun x => x > 4
/-- info: false -/
#guard_msgs in
#eval m.any fun x => x = 0
/-- info: true -/
#guard_msgs in
#eval m.all fun x => x < 2^30
/-- info: false -/
#guard_msgs in
#eval m.all fun x => x > 4
/-- info: [1000000000, 2, 1] -/
#guard_msgs in
#eval m.toList