Skip to content

Commit ad41875

Browse files
committed
monadic
1 parent 3cc63de commit ad41875

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed

src/Init/Data/Iterators/Consumers/Monadic/Loop.lean

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,33 @@ def IterM.Partial.all {α β : Type w} {m : Type w → Type w'} [Monad m]
579579
(p : β → Bool) (it : IterM.Partial (α := α) m β) : m (ULift Bool) := do
580580
it.allM (fun x => pure (.up (p x)))
581581

582+
@[inline]
583+
def IterM.findSomeM? {α β γ : Type w} {m : Type w → Type w'} [Monad m] [Iterator α m β]
584+
[IteratorLoop α m m] [Finite α m] (it : IterM (α := α) m β) (f : β → m (Option γ)) :
585+
m (Option γ) :=
586+
ForIn.forIn it none (fun x _ => do
587+
match ← f x with
588+
| none => return .yield none
589+
| some fx => return .done (some fx))
590+
591+
@[inline]
592+
def IterM.findSome? {α β γ : Type w} {m : Type w → Type w'} [Monad m] [Iterator α m β]
593+
[IteratorLoop α m m] [Finite α m] (it : IterM (α := α) m β) (f : β → Option γ) :
594+
m (Option γ) :=
595+
it.findSomeM? (pure <| f ·)
596+
597+
@[inline]
598+
def IterM.findM? {α β : Type w} {m : Type w → Type w'} [Monad m] [Iterator α m β]
599+
[IteratorLoop α m m] [Finite α m] (it : IterM (α := α) m β) (f : β → m (ULift Bool)) :
600+
m (Option β) :=
601+
it.findSomeM? (fun x => return if (← f x).down then some x else none)
602+
603+
@[inline]
604+
def IterM.find? {α β : Type w} {m : Type w → Type w'} [Monad m] [Iterator α m β]
605+
[IteratorLoop α m m] [Finite α m] (it : IterM (α := α) m β) (f : β → Bool) :
606+
m (Option β) :=
607+
it.findM? (pure <| .up <| f ·)
608+
582609
section Size
583610

584611
/--

src/Init/Data/Iterators/Lemmas/Consumers/Monadic/Loop.lean

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,4 +513,96 @@ theorem IterM.all_eq_not_any_not {α β : Type w} {m : Type w → Type w'} [Iter
513513
· simp [ihs ‹_›]
514514
· simp
515515

516+
theorem IterM.findSomeM?_eq_match_step {α β γ : Type w} {m : Type w → Type w'} [Monad m]
517+
[Iterator α m β] [IteratorLoop α m m] [LawfulMonad m] [Finite α m] [LawfulIteratorLoop α m m]
518+
{it : IterM (α := α) m β} {f : β → m (Option γ)} :
519+
it.findSomeM? f = (do
520+
match (← it.step).val with
521+
| .yield it' out =>
522+
match ← f out with
523+
| none => it'.findSomeM? f
524+
| some fx => return (some fx)
525+
| .skip it' => it'.findSomeM? f
526+
| .done => return none) := by
527+
rw [findSomeM?, forIn_eq_match_step]
528+
apply bind_congr; intro step
529+
cases step using PlausibleIterStep.casesOn
530+
· simp only [bind_assoc]
531+
apply bind_congr; intro fx
532+
split <;> simp [findSomeM?]
533+
· simp [findSomeM?]
534+
· simp
535+
536+
theorem IterM.findSome?_eq_findSomeM? {α β γ : Type w} {m : Type w → Type w'} [Monad m]
537+
[Iterator α m β] [IteratorLoop α m m] [Finite α m]
538+
{it : IterM (α := α) m β} {f : β → Option γ} :
539+
it.findSome? f = it.findSomeM? (pure <| f ·) :=
540+
(rfl)
541+
542+
theorem IterM.findSome?_eq_match_step {α β γ : Type w} {m : Type w → Type w'} [Monad m]
543+
[Iterator α m β] [IteratorLoop α m m] [LawfulMonad m] [Finite α m] [LawfulIteratorLoop α m m]
544+
{it : IterM (α := α) m β} {f : β → Option γ} :
545+
it.findSome? f = (do
546+
match (← it.step).val with
547+
| .yield it' out =>
548+
match f out with
549+
| none => it'.findSome? f
550+
| some fx => return (some fx)
551+
| .skip it' => it'.findSome? f
552+
| .done => return none) := by
553+
rw [findSome?_eq_findSomeM?, findSomeM?_eq_match_step]
554+
apply bind_congr; intro step
555+
split <;> simp [findSome?_eq_findSomeM?]
556+
557+
theorem IterM.findM?_eq_findSomeM? {α β : Type w} {m : Type w → Type w'} [Monad m]
558+
[Iterator α m β] [IteratorLoop α m m] [Finite α m]
559+
{it : IterM (α := α) m β} {f : β → m (ULift Bool)} :
560+
it.findM? f = it.findSomeM? (fun x => return if (← f x).down then some x else none) :=
561+
(rfl)
562+
563+
theorem IterM.findM?_eq_match_step {α β : Type w} {m : Type w → Type w'} [Monad m]
564+
[Iterator α m β] [IteratorLoop α m m] [LawfulMonad m] [Finite α m] [LawfulIteratorLoop α m m]
565+
{it : IterM (α := α) m β} {f : β → m (ULift Bool)} :
566+
it.findM? f = (do
567+
match (← it.step).val with
568+
| .yield it' out =>
569+
if (← f out).down then return (some out) else it'.findM? f
570+
| .skip it' => it'.findM? f
571+
| .done => return none) := by
572+
rw [findM?_eq_findSomeM?, findSomeM?_eq_match_step]
573+
apply bind_congr; intro step
574+
split
575+
· simp only [bind_assoc]
576+
apply bind_congr; intro fx
577+
split <;> simp [findM?_eq_findSomeM?]
578+
· simp [findM?_eq_findSomeM?]
579+
· simp
580+
581+
theorem IterM.find?_eq_findM? {α β : Type w} {m : Type w → Type w'} [Monad m] [Iterator α m β]
582+
[IteratorLoop α m m] [Finite α m] {it : IterM (α := α) m β} {f : β → Bool} :
583+
it.find? f = it.findM? (pure <| .up <| f ·) :=
584+
(rfl)
585+
586+
theorem IterM.find?_eq_findSome? {α β : Type w} {m : Type w → Type w'} [Monad m] [Iterator α m β]
587+
[IteratorLoop α m m] [LawfulMonad m] [Finite α m] {it : IterM (α := α) m β} {f : β → Bool} :
588+
it.find? f = it.findSome? (fun x => if f x then some x else none) := by
589+
simp [find?_eq_findM?, findSome?_eq_findSomeM?, findM?_eq_findSomeM?]
590+
591+
theorem IterM.find?_eq_match_step {α β : Type w} {m : Type w → Type w'} [Monad m]
592+
[Iterator α m β] [IteratorLoop α m m] [LawfulMonad m] [Finite α m] [LawfulIteratorLoop α m m]
593+
{it : IterM (α := α) m β} {f : β → Bool} :
594+
it.find? f = (do
595+
match (← it.step).val with
596+
| .yield it' out =>
597+
if f out then return (some out) else it'.find? f
598+
| .skip it' => it'.find? f
599+
| .done => return none) := by
600+
rw [find?_eq_findM?, findM?_eq_match_step]
601+
apply bind_congr; intro step
602+
split
603+
· simp only [pure_bind]
604+
split <;> simp [find?_eq_findM?]
605+
· simp [find?_eq_findM?]
606+
· simp
607+
516608
end Std.Iterators

0 commit comments

Comments
 (0)