Documentation

Init.Data.Vector.Monadic

Lemmas about Vector.forIn' and Vector.forIn. #

Monadic operations #

theorem Vector.map_toArray_inj {m : Type u_1 → Type u_2} {α : Type u_1} {n : Nat} [Monad m] [LawfulMonad m] [Nonempty α] {v₁ v₂ : m (Vector α n)} (w : toArray <$> v₁ = toArray <$> v₂) :
v₁ = v₂

mapM #

theorem Vector.mapM_congr {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} {β : Type u_1} [Monad m] {as bs : Vector α n} (w : as = bs) {f : αm β} :
mapM f as = mapM f bs
@[simp]
theorem Vector.mapM_mk_empty {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (f : αm β) :
mapM f { toArray := #[], size_toArray := } = pure { toArray := #[], size_toArray := }
@[simp]
theorem Vector.mapM_append {m : Type u_1 → Type u_2} {β : Type u_1} {α : Type u_3} {n n' : Nat} [Monad m] [LawfulMonad m] [Nonempty β] (f : αm β) {l₁ : Vector α n} {l₂ : Vector α n'} :
mapM f (l₁ ++ l₂) = do let __do_liftmapM f l₁ let __do_lift_1mapM f l₂ pure (__do_lift ++ __do_lift_1)

foldlM and foldrM #

theorem Vector.foldlM_map {m : Type u_1 → Type u_2} {β₁ : Type u_3} {β₂ : Type u_4} {α : Type u_1} {n : Nat} [Monad m] (f : β₁β₂) (g : αβ₂m α) (l : Vector β₁ n) (init : α) :
foldlM g init (map f l) = foldlM (fun (x : α) (y : β₁) => g x (f y)) init l
theorem Vector.foldrM_map {m : Type u_1 → Type u_2} {β₁ : Type u_3} {β₂ : Type u_4} {α : Type u_1} {n : Nat} [Monad m] [LawfulMonad m] (f : β₁β₂) (g : β₂αm α) (l : Vector β₁ n) (init : α) :
foldrM g init (map f l) = foldrM (fun (x : β₁) (y : α) => g (f x) y) init l
theorem Vector.foldlM_filterMap {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} {n : Nat} [Monad m] [LawfulMonad m] (f : αOption β) (g : γβm γ) (l : Vector α n) (init : γ) :
Array.foldlM g init (Array.filterMap f l.toArray) = foldlM (fun (x : γ) (y : α) => match f y with | some b => g x b | none => pure x) init l
theorem Vector.foldrM_filterMap {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} {n : Nat} [Monad m] [LawfulMonad m] (f : αOption β) (g : βγm γ) (l : Vector α n) (init : γ) :
Array.foldrM g init (Array.filterMap f l.toArray) = foldrM (fun (x : α) (y : γ) => match f x with | some b => g b y | none => pure y) init l
theorem Vector.foldlM_filter {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} {n : Nat} [Monad m] [LawfulMonad m] (p : αBool) (g : βαm β) (l : Vector α n) (init : β) :
Array.foldlM g init (Array.filter p l.toArray) = foldlM (fun (x : β) (y : α) => if p y = true then g x y else pure x) init l
theorem Vector.foldrM_filter {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} {n : Nat} [Monad m] [LawfulMonad m] (p : αBool) (g : αβm β) (l : Vector α n) (init : β) :
Array.foldrM g init (Array.filter p l.toArray) = foldrM (fun (x : α) (y : β) => if p x = true then g x y else pure y) init l
@[simp]
theorem Vector.foldlM_attachWith {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} {β : Type u_1} [Monad m] (l : Vector α n) {q : αProp} (H : ∀ (a : α), a lq a) {f : β{ x : α // q x }m β} {b : β} :
foldlM f b (l.attachWith q H) = foldlM (fun (b : β) (x : { x : α // x l }) => match x with | a, h => f b a, ) b l.attach
@[simp]
theorem Vector.foldrM_attachWith {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} {β : Type u_1} [Monad m] [LawfulMonad m] (l : Vector α n) {q : αProp} (H : ∀ (a : α), a lq a) {f : { x : α // q x }βm β} {b : β} :
foldrM f b (l.attachWith q H) = foldrM (fun (a : { x : α // x l }) (acc : β) => f a.val, acc) b l.attach

forM #

theorem Vector.forM_congr {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} [Monad m] {as bs : Vector α n} (w : as = bs) {f : αm PUnit} :
forM as f = forM bs f
@[simp]
theorem Vector.forM_append {m : Type u_1 → Type u_2} {α : Type u_3} {n n' : Nat} [Monad m] [LawfulMonad m] (l₁ : Vector α n) (l₂ : Vector α n') (f : αm PUnit) :
forM (l₁ ++ l₂) f = do forM l₁ f forM l₂ f
@[simp]
theorem Vector.forM_map {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} {β : Type u_4} [Monad m] [LawfulMonad m] (l : Vector α n) (g : αβ) (f : βm PUnit) :
forM (map g l) f = forM l fun (a : α) => f (g a)

forIn' #

theorem Vector.forIn'_congr {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} {β : Type u_1} [Monad m] {as bs : Vector α n} (w : as = bs) {b b' : β} (hb : b = b') {f : (a' : α) → a' asβm (ForInStep β)} {g : (a' : α) → a' bsβm (ForInStep β)} (h : ∀ (a : α) (m_1 : a bs) (b : β), f a b = g a m_1 b) :
forIn' as b f = forIn' bs b' g
theorem Vector.forIn'_eq_foldlM {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} {β : Type u_1} [Monad m] [LawfulMonad m] (l : Vector α n) (f : (a : α) → a lβm (ForInStep β)) (init : β) :
forIn' l init f = ForInStep.value <$> foldlM (fun (b : ForInStep β) (x : { x : α // x l }) => match x with | a, m_1 => match b with | ForInStep.yield b => f a m_1 b | ForInStep.done b => pure (ForInStep.done b)) (ForInStep.yield init) l.attach

We can express a for loop over a vector as a fold, in which whenever we reach .done b we keep that value through the rest of the fold.

@[simp]
theorem Vector.forIn'_yield_eq_foldlM {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} {β γ : Type u_1} [Monad m] [LawfulMonad m] (l : Vector α n) (f : (a : α) → a lβm γ) (g : (a : α) → a lβγβ) (init : β) :
(forIn' l init fun (a : α) (m_1 : a l) (b : β) => (fun (c : γ) => ForInStep.yield (g a m_1 b c)) <$> f a m_1 b) = foldlM (fun (b : β) (x : { x : α // x l }) => match x with | a, m_1 => g a m_1 b <$> f a m_1 b) init l.attach

We can express a for loop over a vector which always yields as a fold.

theorem Vector.forIn'_pure_yield_eq_foldl {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} {β : Type u_1} [Monad m] [LawfulMonad m] (l : Vector α n) (f : (a : α) → a lββ) (init : β) :
(forIn' l init fun (a : α) (m_1 : a l) (b : β) => pure (ForInStep.yield (f a m_1 b))) = pure (foldl (fun (b : β) (x : { x : α // x l }) => match x with | a, h => f a h b) init l.attach)
@[simp]
theorem Vector.forIn'_yield_eq_foldl {α : Type u_1} {n : Nat} {β : Type u_2} (l : Vector α n) (f : (a : α) → a lββ) (init : β) :
(forIn' l init fun (a : α) (m : a l) (b : β) => ForInStep.yield (f a m b)) = foldl (fun (b : β) (x : { x : α // x l }) => match x with | a, h => f a h b) init l.attach
@[simp]
theorem Vector.forIn'_map {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} {β : Type u_4} {γ : Type u_1} {init : γ} [Monad m] [LawfulMonad m] (l : Vector α n) (g : αβ) (f : (b : β) → b map g lγm (ForInStep γ)) :
forIn' (map g l) init f = forIn' l init fun (a : α) (h : a l) (y : γ) => f (g a) y
theorem Vector.forIn_eq_foldlM {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} {n : Nat} [Monad m] [LawfulMonad m] (f : αβm (ForInStep β)) (init : β) (l : Vector α n) :
forIn l init f = ForInStep.value <$> foldlM (fun (b : ForInStep β) (a : α) => match b with | ForInStep.yield b => f a b | ForInStep.done b => pure (ForInStep.done b)) (ForInStep.yield init) l

We can express a for loop over a vector as a fold, in which whenever we reach .done b we keep that value through the rest of the fold.

@[simp]
theorem Vector.forIn_yield_eq_foldlM {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} {β γ : Type u_1} [Monad m] [LawfulMonad m] (l : Vector α n) (f : αβm γ) (g : αβγβ) (init : β) :
(forIn l init fun (a : α) (b : β) => (fun (c : γ) => ForInStep.yield (g a b c)) <$> f a b) = foldlM (fun (b : β) (a : α) => g a b <$> f a b) init l

We can express a for loop over a vector which always yields as a fold.

theorem Vector.forIn_pure_yield_eq_foldl {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} {β : Type u_1} [Monad m] [LawfulMonad m] (l : Vector α n) (f : αββ) (init : β) :
(forIn l init fun (a : α) (b : β) => pure (ForInStep.yield (f a b))) = pure (foldl (fun (b : β) (a : α) => f a b) init l)
@[simp]
theorem Vector.forIn_yield_eq_foldl {α : Type u_1} {n : Nat} {β : Type u_2} (l : Vector α n) (f : αββ) (init : β) :
(forIn l init fun (a : α) (b : β) => ForInStep.yield (f a b)) = foldl (fun (b : β) (a : α) => f a b) init l
@[simp]
theorem Vector.forIn_map {m : Type u_1 → Type u_2} {α : Type u_3} {n : Nat} {β : Type u_4} {γ : Type u_1} {init : γ} [Monad m] [LawfulMonad m] (l : Vector α n) (g : αβ) (f : βγm (ForInStep γ)) :
forIn (map g l) init f = forIn l init fun (a : α) (y : γ) => f (g a) y