lean4-htt/src/Lean/Meta/Iterator.lean
2025-07-25 12:02:51 +00:00

79 lines
1.7 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Joe Hendrix
-/
module
prelude
public import Lean.Meta.Basic
public section
namespace Lean.Meta
/--
Provides an interface for iterating over values that are bundled with the `Meta` state
they are valid in.
-/
protected structure Iterator (α : Type) where
/-- Function for getting next value and state pair. -/
next : MetaM (Option (α × Meta.SavedState))
namespace Iterator
/--
Convert a list into an iterator with the current state.
-/
def ofList (l : List α) : MetaM (Meta.Iterator α) := do
let s ← saveState
let ref ← IO.mkRef l
let next := do
restoreState s
match ← ref.get with
| [] =>
pure none
| r :: l =>
ref.set l
pure <| some (r, ←saveState)
pure { next }
/--
Map and filter results of iterator and returning only those values returned
by `f`.
-/
partial def filterMapM (f : α → MetaM (Option β)) (L : Meta.Iterator α) : Meta.Iterator β :=
{ next := _next }
where _next := do
match ← L.next with
| none =>
pure none
| some (v, s) =>
restoreState s
let r ← f v
match r with
| none =>
_next
| some r =>
pure <| some (r, ←saveState)
/--
Find the first value in the iterator while resetting state or call `failure`
if empty.
-/
def head (L : Meta.Iterator α) : MetaM α := do
match ← L.next with
| none =>
failure
| some (x, s) =>
restoreState s
pure x
/--
Return the first value returned by the iterator that `f` succeeds on.
-/
def firstM (L : Meta.Iterator α) (f : α → MetaM (Option β)) : MetaM β := L.filterMapM f |>.head
end Iterator
end Lean.Meta