Documentation

Init.Data.List.Monadic

Lemmas about List.mapM and List.forM. #

Monadic operations #

mapM #

def List.mapM' {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (f : α → m β) :
List α → m (List β)

Applies the monadic action f on every element in the list, left-to-right, and returns the list of results.

This is a non-tail-recursive variant of List.mapM that's easier to reason about. It cannot be used as the main definition and replaced by the tail-recursive version because they can only be proved equal when m is a LawfulMonad.

Equations
Instances For
    @[simp]
    theorem List.mapM'_nil {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] {f : α → m β} :
    @[simp]
    theorem List.mapM'_cons {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} {a : α} {l : List α} [Monad m] {f : α → m β} :
    mapM' f (a :: l) = do let __do_lift ← f a let __do_lift_1 ← mapM' f l pure (__do_lift :: __do_lift_1)
    theorem List.mapM'_eq_mapM {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {f : α → m β} {l : List α} :
    mapM' f l = mapM f l
    @[simp]
    theorem List.mapM_nil {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] {f : α → m β} :
    @[simp]
    theorem List.mapM_cons {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} {a : α} {l : List α} [Monad m] [LawfulMonad m] {f : α → m β} :
    mapM f (a :: l) = do let __do_lift ← f a let __do_lift_1 ← mapM f l pure (__do_lift :: __do_lift_1)
    @[simp]
    theorem List.mapM_pure {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {l : List α} {f : α → β} :
    mapM (fun (x : α) => pure (f x)) l = pure (map f l)
    @[simp]
    theorem List.idRun_mapM {α : Type u_1} {β : Type u_2} {l : List α} {f : α → Id β} :
    (mapM f l).run = map (fun (x : α) => (f x).run) l
    @[simp]
    theorem List.mapM_map {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} [Monad m] [LawfulMonad m] {f : α → β} {g : β → m γ} {l : List α} :
    mapM g (map f l) = mapM (g ∘ f) l
    @[simp]
    theorem List.mapM_append {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {f : α → m β} {l₁ l₂ : List α} :
    mapM f (l₁ ++ l₂) = do let __do_lift ← mapM f l₁ let __do_lift_1 ← mapM f l₂ pure (__do_lift ++ __do_lift_1)
    theorem List.foldlM_cons_eq_append {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {f : α → m β} {as : List α} {b : β} {bs : List β} :
    foldlM (fun (acc : List β) (a : α) => (fun (x : β) => x :: acc) <$> f a) (b :: bs) as = (fun (x : List β) => x ++ b :: bs) <$> foldlM (fun (acc : List β) (a : α) => (fun (x : β) => x :: acc) <$> f a) [] as

    Auxiliary lemma for mapM_eq_reverse_foldlM_cons.

    theorem List.mapM_eq_reverse_foldlM_cons {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {f : α → m β} {l : List α} :
    mapM f l = reverse <$> foldlM (fun (acc : List β) (a : α) => (fun (x : β) => x :: acc) <$> f a) [] l

    filterMapM #

    @[simp]
    theorem List.filterMapM_nil {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] {f : α → m (Option β)} :
    theorem List.filterMapM_loop_eq {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {f : α → m (Option β)} {l : List α} {acc : List β} :
    filterMapM.loop f l acc = (fun (x : List β) => acc.reverse ++ x) <$> filterMapM.loop f l []
    @[simp]
    theorem List.filterMapM_cons {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} {a : α} {l : List α} [Monad m] [LawfulMonad m] {f : α → m (Option β)} :
    filterMapM f (a :: l) = do let __do_lift ← f a match __do_lift with | none => filterMapM f l | some b => do let __do_lift ← filterMapM f l pure (b :: __do_lift)

    zipWithM #

    def List.zipWithM' {m : Type u → Type v} [Monad m] {α : Type w} {β : Type x} {γ : Type u} (f : α → β → m γ) (xs : List α) (ys : List β) :
    m (List γ)

    Applies the monadic action f to the corresponding elements of two lists, left-to-right, stopping at the end of the shorter list. zipWithM' f as bs is equivalent to mapM id (zipWith f as bs) for lawful Monad instances.

    Equations
    Instances For
      @[simp]
      theorem List.zipWithM'_nil_left {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} {l : List β} [Monad m] {f : α → β → m γ} :
      @[simp]
      theorem List.zipWithM'_nil_right {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} {l : List α} [Monad m] {f : α → β → m γ} :
      @[simp]
      theorem List.zipWithM'_cons_cons {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} {a : α} {as : List α} {b : β} {bs : List β} [Monad m] {f : α → β → m γ} :
      zipWithM' f (a :: as) (b :: bs) = do let __do_lift ← f a b let __do_lift_1 ← zipWithM' f as bs pure (__do_lift :: __do_lift_1)
      theorem List.zipWithM'_eq_zipWithM {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} [Monad m] [LawfulMonad m] {f : α → β → m γ} {l : List α} {l' : List β} :
      zipWithM' f l l' = zipWithM f l l'
      @[simp]
      theorem List.zipWithM_nil_left {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} {l : List β} [Monad m] {f : α → β → m γ} :
      @[simp]
      theorem List.zipWithM_nil_right {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} {l : List α} [Monad m] {f : α → β → m γ} :
      @[simp]
      theorem List.zipWithM_cons_cons {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} {a : α} {as : List α} {b : β} {bs : List β} [Monad m] [LawfulMonad m] {f : α → β → m γ} :
      zipWithM f (a :: as) (b :: bs) = do let __do_lift ← f a b let __do_lift_1 ← zipWithM f as bs pure (__do_lift :: __do_lift_1)
      @[simp]
      theorem List.zipWithM'_eq_mapM_id_zipWith {α : Type u_1} {β : Type u_2} {γ : Type v} {m : Type v → Type w} [Monad m] [LawfulMonad m] {f : α → β → m γ} {as : List α} {bs : List β} :
      zipWithM' f as bs = mapM id (zipWith f as bs)

      flatMapM #

      @[simp]
      theorem List.flatMapM_nil {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] {f : α → m (List β)} :
      theorem List.flatMapM_loop_eq {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {f : α → m (List β)} {l : List α} {acc : List (List β)} :
      flatMapM.loop f l acc = (fun (x : List β) => acc.reverse.flatten ++ x) <$> flatMapM.loop f l []
      @[simp]
      theorem List.flatMapM_cons {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} {a : α} {l : List α} [Monad m] [LawfulMonad m] {f : α → m (List β)} :
      flatMapM f (a :: l) = do let bs ← f a let __do_lift ← flatMapM f l pure (bs ++ __do_lift)

      foldlM and foldrM #

      theorem List.foldlM_map {m : Type u_1 → Type u_2} {β₁ : Type u_3} {β₂ : Type u_4} {α : Type u_1} [Monad m] {f : β₁ → β₂} {g : α → β₂ → m α} {l : List β₁} {init : α} :
      foldlM g init (map f l) = foldlM (fun (x : α) (y : β₁) => g x (f y)) init l
      theorem List.foldrM_map {m : Type u_1 → Type u_2} {β₁ : Type u_3} {β₂ : Type u_4} {α : Type u_1} [Monad m] [LawfulMonad m] {f : β₁ → β₂} {g : β₂ → α → m α} {l : List β₁} {init : α} :
      foldrM g init (map f l) = foldrM (fun (x : β₁) (y : α) => g (f x) y) init l
      theorem List.foldlM_filterMap {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} [Monad m] [LawfulMonad m] {f : α → Option β} {g : γ → β → m γ} {l : List α} {init : γ} :
      foldlM g init (filterMap f l) = foldlM (fun (x : γ) (y : α) => match f y with | some b => g x b | none => pure x) init l
      theorem List.foldrM_filterMap {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} [Monad m] [LawfulMonad m] {f : α → Option β} {g : β → γ → m γ} {l : List α} {init : γ} :
      foldrM g init (filterMap f l) = foldrM (fun (x : α) (y : γ) => match f x with | some b => g b y | none => pure y) init l
      theorem List.foldlM_filter {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {p : α → Bool} {g : β → α → m β} {l : List α} {init : β} :
      foldlM g init (filter p l) = foldlM (fun (x : β) (y : α) => if p y = true then g x y else pure x) init l
      theorem List.foldrM_filter {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {p : α → Bool} {g : α → β → m β} {l : List α} {init : β} :
      foldrM g init (filter p l) = foldrM (fun (x : α) (y : β) => if p x = true then g x y else pure y) init l
      @[simp]
      theorem List.foldlM_attachWith {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] {l : List α} {q : α → Prop} (H : ∀ (a : α), a ∈ l → q 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 List.foldrM_attachWith {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {l : List α} {q : α → Prop} (H : ∀ (a : α), a ∈ l → q 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 #

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

      forIn' #

      theorem List.forIn'_loop_congr {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} {xs : List α} [Monad m] {as bs : List α} {f : (a' : α) → a' ∈ as → β → m (ForInStep β)} {g : (a' : α) → a' ∈ bs → β → m (ForInStep β)} {b : β} (ha : ∃ (ys : List α), ys ++ xs = as) (hb : ∃ (ys : List α), ys ++ xs = bs) (h : ∀ (a : α) (m_1 : a ∈ as) (m' : a ∈ bs) (b : β), f a m_1 b = g a m' b) :
      forIn'.loop as f xs b ha = forIn'.loop bs g xs b hb
      @[simp]
      theorem List.forIn'_cons {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] {a : α} {as : List α} (f : (a' : α) → a' ∈ a :: as → β → m (ForInStep β)) (b : β) :
      forIn' (a :: as) b f = do let x ← f a ⋯ b match x with | ForInStep.done b => pure b | ForInStep.yield b => forIn' as b fun (a' : α) (m : a' ∈ as) (b : β) => f a' ⋯ b
      @[simp]
      theorem List.forIn_cons {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (f : α → β → m (ForInStep β)) (a : α) (as : List α) (b : β) :
      forIn (a :: as) b f = do let x ← f a b match x with | ForInStep.done b => pure b | ForInStep.yield b => forIn as b f
      theorem List.forIn'_congr {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] {as bs : List α} (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 List.forIn'_eq_foldlM {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {l : List α} (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 list as a fold, in which whenever we reach .done b we keep that value through the rest of the fold.

      @[simp]
      theorem List.forIn'_yield_eq_foldlM {m : Type u_1 → Type u_2} {α : Type u_3} {β γ : Type u_1} [Monad m] [LawfulMonad m] {l : List α} (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 list which always yields as a fold.

      @[simp]
      theorem List.forIn'_pure_yield_eq_foldl {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {l : List α} (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 List.idRun_forIn'_yield_eq_foldl {α : Type u_1} {β : Type u_2} (l : List α) (f : (a : α) → a ∈ l → β → Id β) (init : β) :
      (forIn' l init fun (a : α) (m : a ∈ l) (b : β) => ForInStep.yield <$> f a m b).run = foldl (fun (b : β) (x : { x : α // x ∈ l }) => match x with | ⟨a, h⟩ => (f a h b).run) init l.attach
      @[simp]
      theorem List.forIn'_map {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} {init : γ} [Monad m] [LawfulMonad m] {l : List α} (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 List.forIn_eq_foldlM {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {l : List α} (f : α → β → m (ForInStep β)) (init : β) :
      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 list as a fold, in which whenever we reach .done b we keep that value through the rest of the fold.

      @[simp]
      theorem List.forIn_yield_eq_foldlM {m : Type u_1 → Type u_2} {α : Type u_3} {β γ : Type u_1} [Monad m] [LawfulMonad m] {l : List α} (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 list which always yields as a fold.

      @[simp]
      theorem List.forIn_pure_yield_eq_foldl {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {l : List α} (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 List.idRun_forIn_yield_eq_foldl {α : Type u_1} {β : Type u_2} (l : List α) (f : α → β → Id β) (init : β) :
      (forIn l init fun (a : α) (b : β) => ForInStep.yield <$> f a b).run = foldl (fun (b : β) (a : α) => (f a b).run) init l
      @[simp]
      theorem List.forIn_map {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_4} {γ : Type u_1} {init : γ} [Monad m] [LawfulMonad m] {l : List α} {g : α → β} {f : β → γ → m (ForInStep γ)} :
      forIn (map g l) init f = forIn l init fun (a : α) (y : γ) => f (g a) y

      allM and anyM #

      theorem List.allM_eq_not_anyM_not {m : Type → Type u_1} {α : Type u_2} [Monad m] [LawfulMonad m] {p : α → m Bool} {as : List α} :
      allM p as = (fun (x : Bool) => !x) <$> anyM (fun (x : α) => (fun (x : Bool) => !x) <$> p x) as
      @[simp]
      theorem List.anyM_pure {m : Type → Type u_1} {α : Type u_2} [Monad m] [LawfulMonad m] {p : α → Bool} {as : List α} :
      anyM (fun (x : α) => pure (p x)) as = pure (as.any p)
      @[simp]
      theorem List.anyM_nil {m : Type → Type u_1} {α : Type u_2} [Monad m] {p : α → m Bool} :
      @[simp]
      theorem List.anyM_cons {m : Type → Type u_1} {α : Type u_2} [Monad m] {p : α → m Bool} {x : α} {xs : List α} :
      anyM p (x :: xs) = do let __do_lift ← p x if __do_lift = true then pure true else anyM p xs
      @[simp]
      theorem List.allM_pure {m : Type → Type u_1} {α : Type u_2} [Monad m] [LawfulMonad m] {p : α → Bool} {as : List α} :
      allM (fun (x : α) => pure (p x)) as = pure (as.all p)
      @[simp]
      theorem List.allM_nil {m : Type → Type u_1} {α : Type u_2} [Monad m] {p : α → m Bool} :
      @[simp]
      theorem List.allM_cons {m : Type → Type u_1} {α : Type u_2} [Monad m] {p : α → m Bool} {x : α} {xs : List α} :
      allM p (x :: xs) = do let __do_lift ← p x if __do_lift = true then allM p xs else pure false

      Recognizing higher order functions using a function that only depends on the value. #

      @[simp]
      theorem List.foldlM_subtype {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] {p : α → Prop} {l : List { x : α // p x }} {f : β → { x : α // p x } → m β} {g : β → α → m β} {x : β} (hf : ∀ (b : β) (x : α) (h : p x), f b ⟨x, h⟩ = g b x) :
      foldlM f x l = foldlM g x l.unattach

      This lemma identifies monadic folds over lists of subtypes, where the function only depends on the value, not the proposition, and simplifies these to the function directly taking the value.

      theorem List.foldlM_wfParam {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] {xs : List α} {f : β → α → m β} {init : β} :
      foldlM f init (wfParam xs) = foldlM f init xs.attach.unattach
      theorem List.foldlM_unattach {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] {P : α → Prop} {xs : List (Subtype P)} {f : β → α → m β} {init : β} :
      foldlM f init xs.unattach = foldlM (fun (b : β) (x : Subtype P) => match x with | ⟨x, h⟩ => binderNameHint b f (binderNameHint x (f b) (binderNameHint h () (f b (wfParam x))))) init xs
      @[simp]
      theorem List.foldrM_subtype {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {p : α → Prop} {l : List { x : α // p x }} {f : { x : α // p x } → β → m β} {g : α → β → m β} {x : β} (hf : ∀ (x : α) (h : p x) (b : β), f ⟨x, h⟩ b = g x b) :
      foldrM f x l = foldrM g x l.unattach

      This lemma identifies monadic folds over lists of subtypes, where the function only depends on the value, not the proposition, and simplifies these to the function directly taking the value.

      theorem List.foldrM_wfParam {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {xs : List α} {f : α → β → m β} {init : β} :
      foldrM f init (wfParam xs) = foldrM f init xs.attach.unattach
      theorem List.foldrM_unattach {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {P : α → Prop} {xs : List (Subtype P)} {f : α → β → m β} {init : β} :
      foldrM f init xs.unattach = foldrM (fun (x : Subtype P) (b : β) => match x with | ⟨x, h⟩ => binderNameHint x f (binderNameHint h () (binderNameHint b (f x) (f (wfParam x) b)))) init xs
      @[simp]
      theorem List.mapM_subtype {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {p : α → Prop} {l : List { x : α // p x }} {f : { x : α // p x } → m β} {g : α → m β} (hf : ∀ (x : α) (h : p x), f ⟨x, h⟩ = g x) :

      This lemma identifies monadic maps over lists of subtypes, where the function only depends on the value, not the proposition, and simplifies these to the function directly taking the value.

      theorem List.mapM_wfParam {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {xs : List α} {f : α → m β} :
      theorem List.mapM_unattach {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {P : α → Prop} {xs : List (Subtype P)} {f : α → m β} :
      mapM f xs.unattach = mapM (fun (x : Subtype P) => match x with | ⟨x, h⟩ => binderNameHint x f (binderNameHint h () (f (wfParam x)))) xs
      @[simp]
      theorem List.filterMapM_subtype {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {p : α → Prop} {l : List { x : α // p x }} {f : { x : α // p x } → m (Option β)} {g : α → m (Option β)} (hf : ∀ (x : α) (h : p x), f ⟨x, h⟩ = g x) :
      theorem List.filterMapM_wfParam {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {xs : List α} {f : α → m (Option β)} :
      theorem List.filterMapM_unattach {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {P : α → Prop} {xs : List (Subtype P)} {f : α → m (Option β)} :
      filterMapM f xs.unattach = filterMapM (fun (x : Subtype P) => match x with | ⟨x, h⟩ => binderNameHint x f (binderNameHint h () (f (wfParam x)))) xs
      @[simp]
      theorem List.flatMapM_subtype {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {p : α → Prop} {l : List { x : α // p x }} {f : { x : α // p x } → m (List β)} {g : α → m (List β)} (hf : ∀ (x : α) (h : p x), f ⟨x, h⟩ = g x) :
      theorem List.flatMapM_wfParam {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {xs : List α} {f : α → m (List β)} :
      theorem List.flatMapM_unattach {m : Type u_1 → Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] [LawfulMonad m] {P : α → Prop} {xs : List (Subtype P)} {f : α → m (List β)} :
      flatMapM f xs.unattach = flatMapM (fun (x : Subtype P) => match x with | ⟨x, h⟩ => binderNameHint x f (binderNameHint h () (f (wfParam x)))) xs