@@ -62,8 +62,9 @@ class IteratorLoop (α : Type w) (m : Type w → Type w') {β : Type w} [Iterato
6262 forIn : ∀ (_lift : (γ : Type w) → m γ → n γ) (γ : Type w),
6363 (plausible_forInStep : β → γ → ForInStep γ → Prop ) →
6464 IteratorLoop.WellFounded α m plausible_forInStep →
65- IterM (α := α) m β → γ →
66- ((b : β) → (c : γ) → n (Subtype (plausible_forInStep b c))) → n γ
65+ (it : IterM (α := α) m β) → γ →
66+ ((b : β) → it.IsPlausibleIndirectOutput b → (c : γ) → n (Subtype (plausible_forInStep b c))) →
67+ n γ
6768
6869/--
6970`IteratorLoopPartial α m` provides efficient implementations of loop-based consumers for `α`-based
@@ -76,7 +77,8 @@ provided by the standard library.
7677class IteratorLoopPartial (α : Type w) (m : Type w → Type w') {β : Type w} [Iterator α m β]
7778 (n : Type w → Type w'') where
7879 forInPartial : ∀ (_lift : (γ : Type w) → m γ → n γ) {γ : Type w},
79- IterM (α := α) m β → γ → ((b : β) → (c : γ) → n (ForInStep γ)) → n γ
80+ (it : IterM (α := α) m β) → γ →
81+ ((b : β) → it.IsPlausibleIndirectOutput b → (c : γ) → n (ForInStep γ)) → n γ
8082
8183class IteratorSize (α : Type w) (m : Type w → Type w') {β : Type w} [Iterator α m β] where
8284 size : IterM (α := α) m β → m (ULift Nat)
@@ -115,16 +117,20 @@ def IterM.DefaultConsumers.forIn {m : Type w → Type w'} {α : Type w} {β : Ty
115117 (plausible_forInStep : β → γ → ForInStep γ → Prop )
116118 (wf : IteratorLoop.WellFounded α m plausible_forInStep)
117119 (it : IterM (α := α) m β) (init : γ)
118- (f : (b : β) → (c : γ) → n (Subtype (plausible_forInStep b c))) : n γ :=
120+ (f : (b : β) → it.IsPlausibleIndirectOutput b → (c : γ) → n (Subtype (plausible_forInStep b c))) : n γ :=
119121 haveI : WellFounded _ := wf
120122 letI : MonadLift m n := ⟨fun {γ} => lift γ⟩
121123 do
122124 match ← it.step with
123- | .yield it' out _ =>
124- match ← f out init with
125- | ⟨.yield c, _⟩ => IterM.DefaultConsumers.forIn lift _ plausible_forInStep wf it' c f
125+ | .yield it' out h =>
126+ match ← f out (.direct ⟨_, h⟩) init with
127+ | ⟨.yield c, _⟩ =>
128+ IterM.DefaultConsumers.forIn lift _ plausible_forInStep wf it' c
129+ (fun out h' acc => f out (.indirect ⟨_, rfl, h⟩ h') acc)
126130 | ⟨.done c, _⟩ => return c
127- | .skip it' _ => IterM.DefaultConsumers.forIn lift _ plausible_forInStep wf it' init f
131+ | .skip it' h =>
132+ IterM.DefaultConsumers.forIn lift _ plausible_forInStep wf it' init
133+ (fun out h' acc => f out (.indirect ⟨_, rfl, h⟩ h') acc)
128134 | .done _ => return init
129135termination_by IteratorLoop.WFRel.mk wf it init
130136decreasing_by
@@ -159,15 +165,19 @@ partial def IterM.DefaultConsumers.forInPartial {m : Type w → Type w'} {α : T
159165 {n : Type w → Type w''} [Monad n]
160166 (lift : ∀ γ, m γ → n γ) (γ : Type w)
161167 (it : IterM (α := α) m β) (init : γ)
162- (f : (b : β) → (c : γ) → n (ForInStep γ)) : n γ :=
168+ (f : (b : β) → it.IsPlausibleIndirectOutput b → (c : γ) → n (ForInStep γ)) : n γ :=
163169 letI : MonadLift m n := ⟨fun {γ} => lift γ⟩
164170 do
165171 match ← it.step with
166- | .yield it' out _ =>
167- match ← f out init with
168- | .yield c => IterM.DefaultConsumers.forInPartial lift _ it' c f
172+ | .yield it' out h =>
173+ match ← f out (.direct ⟨_, h⟩) init with
174+ | .yield c =>
175+ IterM.DefaultConsumers.forInPartial lift _ it' c
176+ fun out h' acc => f out (.indirect ⟨_, rfl, h⟩ h') acc
169177 | .done c => return c
170- | .skip it' _ => IterM.DefaultConsumers.forInPartial lift _ it' init f
178+ | .skip it' h =>
179+ IterM.DefaultConsumers.forInPartial lift _ it' init
180+ fun out h' acc => f out (.indirect ⟨_, rfl, h⟩ h') acc
171181 | .done _ => return init
172182
173183/--
@@ -202,27 +212,28 @@ theorem IteratorLoop.wellFounded_of_finite {m : Type w → Type w'}
202212 exact WellFoundedRelation.wf
203213
204214/--
205- This `ForIn`-style loop construct traverses a finite iterator using an `IteratorLoop` instance.
215+ This `ForIn' `-style loop construct traverses a finite iterator using an `IteratorLoop` instance.
206216-/
207217@[always_inline, inline]
208- def IteratorLoop.finiteForIn {m : Type w → Type w'} {n : Type w → Type w''}
218+ def IteratorLoop.finiteForIn' {m : Type w → Type w'} {n : Type w → Type w''}
209219 {α : Type w} {β : Type w} [Iterator α m β] [Finite α m] [IteratorLoop α m n]
210220 (lift : ∀ γ, m γ → n γ) :
211- ForIn n (IterM (α := α) m β) β where
212- forIn {γ} [Monad n] it init f :=
221+ ForIn' n (IterM (α := α) m β) β ⟨ fun it out => it.IsPlausibleIndirectOutput out⟩ where
222+ forIn' {γ} [Monad n] it init f :=
213223 IteratorLoop.forIn (α := α) (m := m) lift γ (fun _ _ _ => True)
214224 wellFounded_of_finite
215- it init ((⟨·, .intro⟩) <$> f · · )
225+ it init (fun out h acc => (⟨·, .intro⟩) <$> f out h acc )
216226
217227instance {m : Type w → Type w'} {n : Type w → Type w''}
218228 {α : Type w} {β : Type w} [Iterator α m β] [Finite α m] [IteratorLoop α m n]
219229 [MonadLiftT m n] :
220- ForIn n (IterM (α := α) m β) β := IteratorLoop.finiteForIn (fun _ => monadLift)
230+ ForIn' n (IterM (α := α) m β) β ⟨fun it out => it.IsPlausibleIndirectOutput out⟩ :=
231+ IteratorLoop.finiteForIn' (fun _ => monadLift)
221232
222233instance {m : Type w → Type w'} {n : Type w → Type w''}
223234 {α : Type w} {β : Type w} [Iterator α m β] [IteratorLoopPartial α m n] [MonadLiftT m n] :
224- ForIn n (IterM.Partial (α := α) m β) β where
225- forIn it init f :=
235+ ForIn' n (IterM.Partial (α := α) m β) β ⟨ fun it out => it.it.IsPlausibleIndirectOutput out⟩ where
236+ forIn' it init f :=
226237 IteratorLoopPartial.forInPartial (α := α) (m := m) (fun _ => monadLift) it.it init f
227238
228239instance {m : Type w → Type w'} {n : Type w → Type w''}
0 commit comments