Lean 语言参考手册

20.15. 链表🔗

链表由 归纳类型 List 实现,包含一个有序的元素序列。 不同于 数组,Lean 会按照归纳类型的通常规则来编译列表;不过,借助 csimp 机制,某些列表操作在编译后的代码中会被替换为尾递归的等价实现。 Lean 同时为列表字面量和构造子 List.cons 提供了语法。

🔗归纳类型
List.{u} (α : Type u) : Type u
List.{u} (α : Type u) : Type u

链接列表:有序列表,其中每个元素都有对下一个元素的引用。

链表上的大多数操作所花费的时间与链表的长度成正比,因为每个操作 必须遍历元素才能找到下一个元素。

List αArray α 同构,但它们用于不同的事情:

  • List α 更容易推理,而 Array α 被建模为 List α 的包装器。

  • 当共享尾部的许多副本时,List α 作为持久数据结构可以很好地工作。当 该值不共享,Array α 将具有更好的性能,因为它可以进行破坏性的操作 更新。

List.nil.{u} {α : Type u} : List α

空列表,通常写作 []

标识符中记法的约定:

  • 标识符中 [] 的推荐拼写是 nil

List.cons.{u} {α : Type u} (head : α) (tail : List α) :
  List α

首元素为 head、其余部分为 tail 的列表。 通常写作 head :: tail

标识符中记法的约定:

  • 标识符中 :: 的推荐拼写是 cons

  • 标识符中 [a] 的推荐拼写是 singleton

20.15.1. 语法🔗

列表字面量写在方括号中,列表元素以逗号分隔。 把元素添加到列表头部的构造子 List.cons 用中缀运算符 «term_::_» : term:: 表示。 列表语法既可用于普通项,也可用于模式。

语法列表字面量
term ::= ...
    | [term,*]

The syntax [a, b, c] is shorthand for a :: b :: c :: [], or List.cons a (List.cons b (List.cons c List.nil)). It allows conveniently constructing list literals.

For lists of length at least 64, an alternative desugaring strategy is used which uses let bindings as intermediates as in let left := [d, e, f]; a :: b :: c :: left to avoid creating very deep expressions. Note that this changes the order of evaluation, although it should not be observable unless you use side effecting operations like dbg_trace.

Conventions for notations in identifiers:

  • The recommended spelling of [] in identifiers is nil.

  • The recommended spelling of [a] in identifiers is singleton.

语法列表构造
term ::= ...
    | term :: term

The list whose first element is head, where tail is the rest of the list. Usually written head :: tail.

Conventions for notations in identifiers:

  • The recommended spelling of :: in identifiers is cons.

构造列表

这些例子都彼此等价:

example : List Nat := [1, 2, 3] example : List Nat := 1 :: [2, 3] example : List Nat := 1 :: 2 :: [3] example : List Nat := 1 :: 2 :: 3 :: [] example : List Nat := 1 :: 2 :: 3 :: .nil example : List Nat := 1 :: 2 :: .cons 3 .nil example : List Nat := .cons 1 (.cons 2 (.cons 3 .nil))
模式匹配与列表

这些函数都彼此等价:

def split : List α List α × List α | [] => ([], []) | [x] => ([x], []) | x :: x' :: xs => let (ys, zs) := split xs (x :: ys, x' :: zs) def split' : List α List α × List α | .nil => (.nil, .nil) | x :: [] => (.singleton x, .nil) | x :: x' :: xs => let (ys, zs) := split xs (x :: ys, x' :: zs) def split'' : List α List α × List α | .nil => (.nil, .nil) | .cons x .nil => (.singleton x, .nil) | .cons x (.cons x' xs) => let (ys, zs) := split xs (.cons x ys, .cons x' zs)

20.15.2. 性能说明🔗

编译器不会覆盖或修改列表的表示:它们就是链表,每个元素都要经过一次指针间接访问。 计算列表长度需要完整遍历一次列表,而修改列表中的某个元素则需要遍历并重新分配该元素之前的前缀部分。 由于 Lean 使用基于引用计数的内存管理,像 List.map 这样遍历列表、并为原列表中的每个元素分配一个新的 List.cons 构造子的操作,在没有其他引用指向原列表时,可以复用原列表的内存。

由于列表在规约与说明中扮演着重要角色,大多数列表函数都尽可能直接地用结构递归编写。 这使得按归纳法编写证明更容易,但也意味着这些操作会消耗与列表长度成比例的栈空间。 许多列表函数都存在与其非尾递归版本等价的尾递归版本,但在推理时更难使用。 在编译后的代码中,尾递归版本会自动替代非尾递归版本。

20.15.3. 接口参考🔗

20.15.3.1. 谓词与关系🔗

🔗定义
List.IsPrefix.{u} {α : Type u} (l₁ l₂ : List α) : Prop
List.IsPrefix.{u} {α : Type u} (l₁ l₂ : List α) : Prop

第一个列表是第二个列表的前缀。

IsPrefix l₁ l₂ 写作 l₁ <+: l₂,表示存在一些 t : List α,使得 l₂ 具有 l₁ ++ t 的形式。

函数 List.isPrefixOf 是布尔值等价函数。

标识符中的符号约定:

  • 标识符中 <+: 的建议拼写为 prefix(而不是 isPrefix)。

语法列表前缀
term ::= ...
    | term <+: term

The first list is a prefix of the second.

IsPrefix l₁ l₂, written l₁ <+: l₂, means that there exists some t : List α such that l₂ has the form l₁ ++ t.

The function List.isPrefixOf is a Boolean equivalent.

Conventions for notations in identifiers:

  • The recommended spelling of <+: in identifiers is prefix (not isPrefix).

🔗定义
List.IsSuffix.{u} {α : Type u} (l₁ l₂ : List α) : Prop
List.IsSuffix.{u} {α : Type u} (l₁ l₂ : List α) : Prop

第一个列表是第二个列表的后缀。

IsSuffix l₁ l₂ 写作 l₁ <:+ l₂,表示存在一些 t : List α,使得 l₂ 具有 t ++ l₁ 的形式。

函数 List.isSuffixOf 是布尔值等价函数。

标识符中的符号约定:

  • 标识符中 <:+ 的建议拼写为 suffix(而不是 isSuffix)。

语法列表后缀
term ::= ...
    | term <:+ term

The first list is a suffix of the second.

IsSuffix l₁ l₂, written l₁ <:+ l₂, means that there exists some t : List α such that l₂ has the form t ++ l₁.

The function List.isSuffixOf is a Boolean equivalent.

Conventions for notations in identifiers:

  • The recommended spelling of <:+ in identifiers is suffix (not isSuffix).

🔗定义
List.IsInfix.{u} {α : Type u} (l₁ l₂ : List α) : Prop
List.IsInfix.{u} {α : Type u} (l₁ l₂ : List α) : Prop

第一个列表是第二个列表的连续子列表。通常用 <:+: 运算符编写。

换句话说,l₁ <:+: l₂ 表示存在列表 s : List αt : List α,使得 l₂ 具有 s ++ l₁ ++ t 的形式。

标识符中的符号约定:

  • 标识符中 <:+: 的建议拼写为 infix(而不是 isInfix)。

语法列表中缀
term ::= ...
    | term <:+: term

The first list is a contiguous sub-list of the second list. Typically written with the <:+: operator.

In other words, l₁ <:+: l₂ means that there exist lists s : List α and t : List α such that l₂ has the form s ++ l₁ ++ t.

Conventions for notations in identifiers:

  • The recommended spelling of <:+: in identifiers is infix (not isInfix).

🔗归纳谓词
List.Sublist.{u_1} {α : Type u_1} : List α List α Prop
List.Sublist.{u_1} {α : Type u_1} : List α List α Prop

第一个列表是第二个列表的不连续子列表。通常用 <+ 运算符编写。

换句话说,l₁ <+ l₂表示通过重复插入新元素,可以将l₁转变为l₂

List.Sublist.slnil.{u_1} {α : Type u_1} : [].Sublist []

基本情形:[][] 的子列表。

List.Sublist.cons.{u_1} {α : Type u_1} {l₁ l₂ : List α}
  (a : α) : l₁.Sublist l₂  l₁.Sublist (a :: l₂)

l₁l₂ 的子序列,则它也是 a :: l₂ 的子序列。

List.Sublist.cons_cons.{u_1} {α : Type u_1} {l₁ l₂ : List α}
  (a : α) : l₁.Sublist l₂  (a :: l₁).Sublist (a :: l₂)

l₁l₂ 的子序列,则 a :: l₁a :: l₂ 的子序列。

语法子列表
term ::= ...
    | term <+ term

The first list is a non-contiguous sub-list of the second list. Typically written with the <+ operator.

In other words, l₁ <+ l₂ means that l₁ can be transformed into l₂ by repeatedly inserting new elements.

只有在打开 List 命名空间时,此语法才可用。

🔗归纳谓词
List.Perm.{u} {α : Type u} : List α List α Prop
List.Perm.{u} {α : Type u} : List α List α Prop

如果两个列表包含相同的元素,并且每个列表出现相同的次数但不一定以相同的顺序,则它们是彼此的排列。

通过展示如何通过重复交换相邻元素将一个列表转换为另一个列表,可以证明一个列表是另一个列表的排列。

List.isPerm 是该关系的布尔等价值。

List.Perm.nil.{u} {α : Type u} : [].Perm []

空列表是空列表的一个排列:[] ~ []

List.Perm.cons.{u} {α : Type u} (x : α) {l₁ l₂ : List α} :
  l₁.Perm l₂  (x :: l₁).Perm (x :: l₂)

若一个列表是另一个列表的排列,则在二者头部添加相同元素后所得的列表也互为排列:l₁ ~ l₂ x::l₁ ~ x::l₂

List.Perm.swap.{u} {α : Type u} (x y : α) (l : List α) :
  (y :: x :: l).Perm (x :: y :: l)

若两个列表除前两个元素互换外完全相同,则它们互为排列:x::y::l ~ y::x::l

List.Perm.trans.{u} {α : Type u} {l₁ l₂ l₃ : List α} :
  l₁.Perm l₂  l₂.Perm l₃  l₁.Perm l₃

排列具有传递性:l₁ ~ l₂ l₂ ~ l₃ l₁ ~ l₃

语法列表置换
term ::= ...
    | term ~ term

Two lists are permutations of each other if they contain the same elements, each occurring the same number of times but not necessarily in the same order.

One list can be proven to be a permutation of another by showing how to transform one into the other by repeatedly swapping adjacent elements.

List.isPerm is a Boolean equivalent of this relation.

只有在打开 List 命名空间时,此语法才可用。

🔗归纳谓词
List.Pairwise.{u} {α : Type u} (R : α α Prop) : List α Prop
List.Pairwise.{u} {α : Type u} (R : α α Prop) : List α Prop

列表中的每个元素都通过 R 与列表中所有后续元素相关。

Pairwise R l 表示 l 中索引较早的所有元素与索引较晚的所有元素都与 R 相关。

例如,Pairwise (· ·) l 断言 l 没有重复项,Pairwise (· < ·) l 断言 l 已(严格)排序。

示例:

  • Pairwise (· < ·) [1, 2, 3] (1 < 2 1 < 3) 2 < 3

  • Pairwise (· = ·) [1, 2, 3] = False

  • Pairwise (· ·) [1, 2, 3] = True

List.Pairwise.nil.{u} {α : Type u} {R : α  α  Prop} :
  List.Pairwise R []

空列表的所有元素之间自然两两满足给定关系。

List.Pairwise.cons.{u} {α : Type u} {R : α  α  Prop}
  {a : α} {l : List α} :
  (∀ (a' : α), a'  l  R a a') 
    List.Pairwise R l  List.Pairwise R (a :: l)

若非空列表的头部与尾部的每个元素都满足关系 R,且尾部自身的元素两两满足该关系,则此列表的元素两两满足该关系。

也就是说,若满足以下条件,则 a :: lPairwise R

  • Ral 的每个元素相关联

  • lPairwise R

🔗定义
List.Nodup.{u} {α : Type u} : List α Prop
List.Nodup.{u} {α : Type u} : List α Prop

该列表没有重复项:它最多包含每个元素一次。

它被定义为Pairwise (· ·):每个元素都不等于所有其他元素。

🔗归纳谓词
List.Lex.{u} {α : Type u} (r : α α Prop) (as bs : List α) : Prop
List.Lex.{u} {α : Type u} (r : α α Prop) (as bs : List α) : Prop

列表的字典顺序与元素的顺序有关。

as 按字典顺序小于 bs,如果

  • as 为空且 bs 非空,或者

  • asbs 均非空,且 as 的头部小于 bs 的头部 r,或

  • asbs 都是非空的,它们的头相等,并且 as 的尾部小于 bs 的尾部。

List.Lex.nil.{u} {α : Type u} {r : α  α  Prop} {a : α}
  {l : List α} : List.Lex r [] (a :: l)

[] 是字典序中的最小元素。

List.Lex.rel.{u} {α : Type u} {r : α  α  Prop} {a₁ : α}
  {l₁ : List α} {a₂ : α} {l₂ : List α} (h : r a₁ a₂) :
  List.Lex r (a₁ :: l₁) (a₂ :: l₂)

若第一个列表的头部小于第二个列表的头部,则第一个列表按字典序小于第二个列表。

List.Lex.cons.{u} {α : Type u} {r : α  α  Prop} {a : α}
  {l₁ l₂ : List α} (h : List.Lex r l₁ l₂) :
  List.Lex r (a :: l₁) (a :: l₂)

若两个列表的头部相同,则它们的尾部决定其字典序。若第一个列表的尾部按字典序小于第二个列表的尾部,则整个第一个列表按字典序小于整个第二个列表。

🔗归纳谓词
List.Mem.{u} {α : Type u} (a : α) : List α Prop
List.Mem.{u} {α : Type u} (a : α) : List α Prop

列表成员关系,通常通过 运算符使用。

a l 表示 a 是列表 l 的元素。元素按 Lean 的逻辑相等关系比较。

相关函数 List.elem 是使用 BEq α 实例的布尔成员测试。

示例:

  • a [x, y, z] a = x a = y a = z

List.Mem.head.{u} {α : Type u} {a : α} (as : List α) :
  List.Mem a (a :: as)

列表的头部是其成员:a a :: as

List.Mem.tail.{u} {α : Type u} {a : α} (b : α)
  {as : List α} : List.Mem a as  List.Mem a (b :: as)

列表尾部的成员也是该列表的成员:a l a b :: l

20.15.3.2. 构造列表🔗

🔗定义
List.singleton.{u} {α : Type u} (a : α) : List α
List.singleton.{u} {α : Type u} (a : α) : List α

构造一个单元素列表。

示例:

🔗定义
List.concat.{u} {α : Type u} : List α α List α
List.concat.{u} {α : Type u} : List α α List α

将一个元素添加到列表的末尾

添加的元素是结果列​​表的最后一个元素。

示例:

🔗定义
List.replicate.{u} {α : Type u} (n : Nat) (a : α) : List α
List.replicate.{u} {α : Type u} (n : Nat) (a : α) : List α

创建一个包含 na 副本的列表。

🔗定义
List.replicateTR.{u} {α : Type u} (n : Nat) (a : α) : List α
List.replicateTR.{u} {α : Type u} (n : Nat) (a : α) : List α

创建一个包含 na 副本的列表。

这是 List.replicate 的尾递归版本。

🔗定义
List.ofFn.{u_1} {α : Type u_1} {n : Nat} (f : Fin n α) : List α
List.ofFn.{u_1} {α : Type u_1} {n : Nat} (f : Fin n α) : List α

通过按顺序将 f 应用于每个潜在索引(从 0 开始)来创建列表。

示例:

  • List.ofFn (n := 3) toString = ["0", "1", "2"]

  • List.ofFn (fun i => #["red", "green", "blue"].get i.val i.isLt) = ["red", "green", "blue"]

🔗定义
List.append.{u_1} {α : Type u_1} (xs ys : List α) : List α
List.append.{u_1} {α : Type u_1} (xs ys : List α) : List α

附加两个列表。通常通过 ++ 运算符使用。

追加列表所需的时间与第一个列表的长度成正比:O(|xs|)

示例:

  • [1, 2, 3] ++ [4, 5] = [1, 2, 3, 4, 5]

  • [] ++ [4, 5] = [4, 5]

  • [1, 2, 3] ++ [] = [1, 2, 3]

🔗定义
List.appendTR.{u} {α : Type u} (as bs : List α) : List α
List.appendTR.{u} {α : Type u} (as bs : List α) : List α

附加两个列表。通常通过 ++ 运算符使用。

追加列表所需的时间与第一个列表的长度成正比:O(|xs|)

这是 List.append 的尾递归版本。

示例:

  • [1, 2, 3] ++ [4, 5] = [1, 2, 3, 4, 5]

  • [] ++ [4, 5] = [4, 5]

  • [1, 2, 3] ++ [] = [1, 2, 3]

🔗定义

返回从 0n(不包括)的数字列表,按升序排列。

O(n)

示例:

  • range 5 = [0, 1, 2, 3, 4]

  • range 0 = []

  • range 2 = [0, 1]

🔗定义
List.range' (start len : Nat) (step : Nat := 1) : List Nat
List.range' (start len : Nat) (step : Nat := 1) : List Nat

返回具有给定长度 len 的数字列表,从 start 开始并增加 每个元素处都有 step

换句话说,List.range' start len step[start, start+step, ..., start+(len-1)*step]

示例:

🔗定义
List.range'TR (s n : Nat) (step : Nat := 1) : List Nat
List.range'TR (s n : Nat) (step : Nat := 1) : List Nat

返回具有给定长度 len 的数字列表,从 start 开始并增加 每个元素处都有 step

换句话说,List.range'TR start len step[start, start+step, ..., start+(len-1)*step]

这是 List.range' 的尾递归版本。

示例:

🔗定义

按顺序列出 Fin n 的所有元素,从 0 开始。

示例:

20.15.3.3. 长度🔗

🔗定义
List.length.{u_1} {α : Type u_1} : List α Nat
List.length.{u_1} {α : Type u_1} : List α Nat

列表的长度。

该函数在编译器中被重写为 lengthTR,它使用常量堆栈空间。

示例:

🔗定义
List.lengthTR.{u_1} {α : Type u_1} (as : List α) : Nat
List.lengthTR.{u_1} {α : Type u_1} (as : List α) : Nat

列表的长度。

这是List.length的尾递归版本,用于实现List.length,无需运行 堆栈空间不足。

示例:

🔗定义
List.isEmpty.{u} {α : Type u} : List α Bool
List.isEmpty.{u} {α : Type u} : List α Bool

检查列表是否为空。

O(1)

示例:

20.15.3.4. 头与尾🔗

🔗定义
List.head.{u} {α : Type u} (as : List α) : as [] α
List.head.{u} {α : Type u} (as : List α) : as [] α

返回非空列表的第一个元素。

🔗定义
List.head?.{u} {α : Type u} : List α Option α
List.head?.{u} {α : Type u} : List α Option α

返回列表中的第一个元素(如果有)。如果列表为空,则返回 none

使用 List.headD 可为空列表提供后备值;使用 List.head! 则会在空列表上触发 panic。

示例:

🔗定义
List.headD.{u} {α : Type u} (as : List α) (fallback : α) : α
List.headD.{u} {α : Type u} (as : List α) (fallback : α) : α

如果有,则返回列表中的第一个元素;如果列表为空,则返回 fallback

使用 List.head? 返回 Option,并使用 List.head! 对空列表触发 panic。

示例:

  • [].headD "empty" = "empty"

  • [].headD 2 = 2

  • ["head", "shoulders", "knees"].headD "toes" = "head"

🔗定义
List.head!.{u_1} {α : Type u_1} [Inhabited α] : List α α
List.head!.{u_1} {α : Type u_1} [Inhabited α] : List α α

返回列表中的第一个元素。如果列表为空,则会触发 panic并返回 default

更安全的替代方案包括:

🔗定义
List.tail.{u} {α : Type u} : List α List α
List.tail.{u} {α : Type u} : List α List α

删除非空列表的第一个元素,返回尾部。当参数为 时,返回 [] 空的。

示例:

🔗定义
List.tail!.{u_1} {α : Type u_1} : List α List α
List.tail!.{u_1} {α : Type u_1} : List α List α

删除非空列表的第一个元素并返回尾部。如果列表为空,则此函数触发 panic 并返回空列表。

更安全的替代方案包括:

  • tail,在输入为空时返回空列表而不触发 panic;

  • tail?,返回 Option

  • tailD,在输入为空时返回后备值。

示例:

  • ["apple", "banana", "grape"].tail! = ["banana", "grape"]

  • ["banana", "grape"].tail! = ["grape"]

🔗定义
List.tail?.{u} {α : Type u} : List α Option (List α)
List.tail?.{u} {α : Type u} : List α Option (List α)

删除非空列表的第一个元素并返回尾部。如果参数为空,则返回 none

替代方案包括 List.tail(失败时返回空列表)、List.tailD(返回显式后备值)和 List.tail!(在空列表上触发 panic)。

示例:

🔗定义
List.tailD.{u} {α : Type u} (l fallback : List α) : List α
List.tailD.{u} {α : Type u} (l fallback : List α) : List α

删除非空列表的第一个元素并返回尾部。如果参数为空,则返回 none

替代方案包括 List.tail(失败时返回空列表)、List.tail?(返回 Option)和 List.tail!(在空列表上触发错误)。

示例:

  • ["apple", "banana", "grape"].tailD ["orange"] = ["banana", "grape"]

  • ["apple"].tailD ["orange"] = []

  • [].tailD ["orange"] = ["orange"]

20.15.3.5. 查找🔗

🔗定义
List.get.{u} {α : Type u} (as : List α) : Fin as.length α
List.get.{u} {α : Type u} (as : List α) : Fin as.length α

返回提供的索引处的元素,从 0 开始计数。

换句话说,对于 i : Fin as.lengthas.get i 返回列表 i 的第 as 个元素。 因为索引是一个受列表长度限制的 Fin,所以索引永远不会越界。

示例:

  • ["spring", "summer", "fall", "winter"].get (2 : Fin 4) = "fall"

  • ["spring", "summer", "fall", "winter"].get (0 : Fin 4) = "spring"

🔗定义
List.getD.{u_1} {α : Type u_1} (as : List α) (i : Nat) (fallback : α) : α
List.getD.{u_1} {α : Type u_1} (as : List α) (i : Nat) (fallback : α) : α

返回给定索引处的元素(从 0 开始计数)。如果索引越界,则返回 fallback

要根据索引是否越界返回 Option,请使用 as[i]?。索引越界时,可使用 as[i]! 触发 panic。

示例:

  • ["spring", "summer", "fall", "winter"].getD 2 "never" = "fall"

  • ["spring", "summer", "fall", "winter"].getD 0 "never" = "spring"

  • ["spring", "summer", "fall", "winter"].getD 4 "never" = "never"

🔗定义
List.getLast.{u} {α : Type u} (as : List α) : as [] α
List.getLast.{u} {α : Type u} (as : List α) : as [] α

返回非空列表的最后一个元素。

示例:

🔗定义
List.getLast?.{u} {α : Type u} : List α Option α
List.getLast?.{u} {α : Type u} : List α Option α

返回列表中的最后一个元素;如果列表为空,则返回 none

替代方案包括 List.getLastD(接受空列表的后备值)和 List.getLast!(在空列表上触发 panic)。

示例:

🔗定义
List.getLastD.{u} {α : Type u} (as : List α) (fallback : α) : α
List.getLastD.{u} {α : Type u} (as : List α) (fallback : α) : α

返回列表中的最后一个元素;如果列表为空,则返回 fallback

替代方案包括 List.getLast?(返回 Option)和 List.getLast!(在空列表上触发 panic)。

示例:

🔗定义
List.getLast!.{u_1} {α : Type u_1} [Inhabited α] : List α α
List.getLast!.{u_1} {α : Type u_1} [Inhabited α] : List α α

返回列表中的最后一个元素。如果列表为空,则触发 panic并返回 default

更安全的替代方案包括:

  • getLast?,返回 Option

  • getLastD,它采用空列表的后备值,以及

  • getLast,需要证明列表非空。

示例:

🔗定义
List.lookup.{u, v} {α : Type u} {β : Type v} [BEq α] : α List (α × β) Option β
List.lookup.{u, v} {α : Type u} {β : Type v} [BEq α] : α List (α × β) Option β

将列表视为将键映射到值的关联列表,返回其键的第一个值 等于指定的键。

O(|l|)

示例:

  • [(1, "one"), (3, "three"), (3, "other")].lookup 3 = some "three"

  • [(1, "one"), (3, "three"), (3, "other")].lookup 2 = none

🔗定义
List.max?.{u} {α : Type u} [Max α] : List α Option α
List.max?.{u} {α : Type u} [Max α] : List α Option α

如果不为空则返回列表中最大的元素,如果为空则返回 none

示例:

🔗定义
List.min?.{u} {α : Type u} [Min α] : List α Option α
List.min?.{u} {α : Type u} [Min α] : List α Option α

如果不为空则返回列表的最小元素,如果为空则返回 none

示例:

20.15.3.6. 查询🔗

🔗定义
List.count.{u} {α : Type u} [BEq α] (a : α) : List α Nat
List.count.{u} {α : Type u} [BEq α] (a : α) : List α Nat

计算某个元素在列表中出现的次数。

示例:

  • [1, 1, 2, 3, 5].count 1 = 2

  • [1, 1, 2, 3, 5].count 5 = 1

  • [1, 1, 2, 3, 5].count 4 = 0

🔗定义
List.countP.{u} {α : Type u} (p : α Bool) (l : List α) : Nat
List.countP.{u} {α : Type u} (p : α Bool) (l : List α) : Nat

计算列表 l 中满足布尔谓词 p 的元素数量。

示例:

  • [1, 2, 3, 4, 5].countP (· % 2 == 0) = 2

  • [1, 2, 3, 4, 5].countP (· < 5) = 4

  • [1, 2, 3, 4, 5].countP (· > 5) = 0

🔗定义
List.idxOf.{u} {α : Type u} [BEq α] (a : α) : List α Nat
List.idxOf.{u} {α : Type u} [BEq α] (a : α) : List α Nat

返回第一个等于 a 的元素的索引,如果没有元素则返回列表的长度 等于 a

示例:

  • ["carrot", "potato", "broccoli"].idxOf "carrot" = 0

  • ["carrot", "potato", "broccoli"].idxOf "broccoli" = 2

  • ["carrot", "potato", "broccoli"].idxOf "tomato" = 3

  • ["carrot", "potato", "broccoli"].idxOf "anything else" = 3

🔗定义
List.idxOf?.{u} {α : Type u} [BEq α] (a : α) : List α Option Nat
List.idxOf?.{u} {α : Type u} [BEq α] (a : α) : List α Option Nat

返回等于 a 的第一个元素的索引,如果没有元素等于 none,则返回 a

示例:

  • ["carrot", "potato", "broccoli"].idxOf? "carrot" = some 0

  • ["carrot", "potato", "broccoli"].idxOf? "broccoli" = some 2

  • ["carrot", "potato", "broccoli"].idxOf? "tomato" = none

  • ["carrot", "potato", "broccoli"].idxOf? "anything else" = none

🔗定义
List.finIdxOf?.{u} {α : Type u} [BEq α] (a : α) (l : List α) : Option (Fin l.length)
List.finIdxOf?.{u} {α : Type u} [BEq α] (a : α) (l : List α) : Option (Fin l.length)

返回第一个等于 a 的元素的索引,如果没有元素则返回列表的长度 等于 a。该索引以 Fin 形式返回,这保证了它在范围内。

示例:

🔗定义
List.find?.{u} {α : Type u} (p : α Bool) : List α Option α
List.find?.{u} {α : Type u} (p : α Bool) : List α Option α

返回列表中谓词 p 返回 true 的第一个元素,如果没有则返回 none 找到了这样的元素。

O(|l|)

示例:

  • [7, 6, 5, 8, 1, 2, 6].find? (· < 5) = some 1

  • [7, 6, 5, 8, 1, 2, 6].find? (· < 1) = none

🔗定义
List.findFinIdx?.{u} {α : Type u} (p : α Bool) (l : List α) : Option (Fin l.length)
List.findFinIdx?.{u} {α : Type u} (p : α Bool) (l : List α) : Option (Fin l.length)

返回 p 返回 true 的第一个元素的索引,如果没有这样的元素,则返回 none 元素。该索引以 Fin 形式返回,这保证了它在范围内。

示例:

🔗定义
List.findIdx.{u} {α : Type u} (p : α Bool) (l : List α) : Nat
List.findIdx.{u} {α : Type u} (p : α Bool) (l : List α) : Nat

返回 p 返回 true 的第一个元素的索引,或者列表的长度(如果) 不存在这样的元素。

示例:

  • [7, 6, 5, 8, 1, 2, 6].findIdx (· < 5) = 4

  • [7, 6, 5, 8, 1, 2, 6].findIdx (· < 1) = 7

🔗定义
List.findIdx?.{u} {α : Type u} (p : α Bool) (l : List α) : Option Nat
List.findIdx?.{u} {α : Type u} (p : α Bool) (l : List α) : Option Nat

返回 p 返回 true 的第一个元素的索引,如果没有这样的元素,则返回 none 元素。

示例:

🔗定义
List.findM?.{u} {m : Type Type u} [Monad m] {α : Type} (p : α m Bool) : List α m (Option α)
List.findM?.{u} {m : Type Type u} [Monad m] {α : Type} (p : α m Bool) : List α m (Option α)

返回单子谓词 p 返回 truenone 的列表的第一个元素 如果没有找到这样的元素。按顺序检查列表的元素。

O(|l|)

示例:

some 1Almost! 6 Almost! 5 #eval [7, 6, 5, 8, 1, 2, 6].findM? fun i => do if i < 5 then return true if i 6 then IO.println s!"Almost! {i}" return false Almost! 6 Almost! 5some 1
🔗定义
List.findSome?.{u, v} {α : Type u} {β : Type v} (f : α Option β) : List α Option β
List.findSome?.{u, v} {α : Type u} {β : Type v} (f : α Option β) : List α Option β

返回按顺序将 none 应用到列表中每个元素的第一个非 f 结果。退货 none 如果 f 对列表的所有元素返回 none

O(|l|)

示例:

🔗定义
List.findSomeM?.{u, v, w} {m : Type u Type v} [Monad m] {α : Type w} {β : Type u} (f : α m (Option β)) : List α m (Option β)
List.findSomeM?.{u, v, w} {m : Type u Type v} [Monad m] {α : Type w} {β : Type u} (f : α m (Option β)) : List α m (Option β)

返回将一元函数 none 应用于每个元素的第一个非 f 结果 列表,按顺序。如果 none 对所有元素返回 f,则返回 none

O(|l|)

示例:

some 10Almost! 6 Almost! 5 #eval [7, 6, 5, 8, 1, 2, 6].findSomeM? fun i => do if i < 5 then return some (i * 10) if i 6 then IO.println s!"Almost! {i}" return none Almost! 6 Almost! 5some 10

20.15.3.7. 转换🔗

🔗定义
List.toArray.{u_1} {α : Type u_1} (xs : List α) : Array α
List.toArray.{u_1} {α : Type u_1} (xs : List α) : Array α

List α 转换为 Array α

O(|xs|)。在运行时,该操作由 List.toArrayImpl 实现,并且花费的时间与 列表的长度。应使用 List.toArray 代替 Array.mk

示例:

  • [1, 2, 3].toArray = #[1, 2, 3]

  • ["monday", "wednesday", friday"].toArray = #["monday", "wednesday", friday"].

🔗定义
List.toArrayImpl.{u_1} {α : Type u_1} (xs : List α) : Array α
List.toArrayImpl.{u_1} {α : Type u_1} (xs : List α) : Array α

通过重复将列表中的元素推入空列表,将 List α 转换为 Array α 数组。 O(|xs|)

使用 List.toArray 而不是直接调用该函数。在运行时,该操作实现 List.toArrayArray.mk

🔗定义

将字节列表转换为 ByteArray

🔗定义
List.toFloatArray (ds : List Float) : FloatArray
List.toFloatArray (ds : List Float) : FloatArray

将浮点数列表转换为 FloatArray

🔗定义
List.toString.{u_1} {α : Type u_1} [ToString α] : List α String
List.toString.{u_1} {α : Type u_1} [ToString α] : List α String

将列表转换为字符串,使用 ToString.toString 转换其元素。

生成的字符串类似于列表文字语法,元素由 ", " 分隔,并且 括在方括号中。

生成的字符串可能不是有效的 Lean 语法,因为没有这样的期望 ToString 实例。

示例:

20.15.3.8. 修改🔗

🔗定义
List.set.{u_1} {α : Type u_1} (l : List α) (n : Nat) (a : α) : List α
List.set.{u_1} {α : Type u_1} (l : List α) (n : Nat) (a : α) : List α

将(从零开始)索引 nl 中所指的值替换为 a。如果索引越界,则列表将不加修改地返回。

示例:

  • ["water", "coffee", "soda", "juice"].set 1 "tea" = ["water", "tea", "soda", "juice"]

  • ["water", "coffee", "soda", "juice"].set 4 "tea" = ["water", "coffee", "soda", "juice"]

🔗定义
List.setTR.{u_1} {α : Type u_1} (l : List α) (n : Nat) (a : α) : List α
List.setTR.{u_1} {α : Type u_1} (l : List α) (n : Nat) (a : α) : List α

将(从零开始)索引 nl 中所指的值替换为 a。如果索引越界,则列表将不加修改地返回。

这是在运行时使用的 List.set 的尾递归版本。

示例:

  • ["water", "coffee", "soda", "juice"].set 1 "tea" = ["water", "tea", "soda", "juice"]

  • ["water", "coffee", "soda", "juice"].set 4 "tea" = ["water", "coffee", "soda", "juice"]

🔗定义
List.modify.{u} {α : Type u} (l : List α) (i : Nat) (f : α α) : List α
List.modify.{u} {α : Type u} (l : List α) (i : Nat) (f : α α) : List α

将给定索引处的元素(如果存在)替换为对其应用 f 的结果。如果索引无效,则列表将不加修改地返回。

示例:

  • [1, 2, 3].modify 0 (· * 10) = [10, 2, 3]

  • [1, 2, 3].modify 2 (· * 10) = [1, 2, 30]

  • [1, 2, 3].modify 3 (· * 10) = [1, 2, 3]

🔗定义
List.modifyTR.{u_1} {α : Type u_1} (l : List α) (i : Nat) (f : α α) : List α
List.modifyTR.{u_1} {α : Type u_1} (l : List α) (i : Nat) (f : α α) : List α

将给定索引处的元素(如果存在)替换为对其应用 f 的结果。

这是 List.modify 的尾递归版本。

示例:

  • [1, 2, 3].modifyTR 0 (· * 10) = [10, 2, 3]

  • [1, 2, 3].modifyTR 2 (· * 10) = [1, 2, 30]

  • [1, 2, 3].modifyTR 3 (· * 10) = [1, 2, 3]

🔗定义
List.modifyHead.{u} {α : Type u} (f : α α) : List α List α
List.modifyHead.{u} {α : Type u} (f : α α) : List α List α

将列表的头部替换为应用 f 的结果。如果列表为空,则返回空列表。

示例:

🔗定义
List.modifyTailIdx.{u} {α : Type u} (l : List α) (i : Nat) (f : List α List α) : List α
List.modifyTailIdx.{u} {α : Type u} (l : List α) (i : Nat) (f : List α List α) : List α

将第 nl 的尾部替换为对其应用 f 的结果。如果索引大于列表的长度,则返回输入而不使用 f

示例:

["circle", "square", "triangle"].modifyTailIdx 1 List.reverse["circle", "triangle", "square"]["circle", "square", "triangle"].modifyTailIdx 1 (fun xs => xs ++ xs)["circle", "square", "triangle", "square", "triangle"]["circle", "square", "triangle"].modifyTailIdx 2 (fun xs => xs ++ xs)["circle", "square", "triangle", "triangle"]["circle", "square", "triangle"].modifyTailIdx 5 (fun xs => xs ++ xs)["circle", "square", "triangle"]
🔗定义
List.erase.{u_1} {α : Type u_1} [BEq α] : List α α List α
List.erase.{u_1} {α : Type u_1} [BEq α] : List α α List α

删除第一次出现的 a,搜索范围为 l。如果 a 未出现在 l 中,则返回未修改的列表。

O(|l|)

示例:

  • [1, 5, 3, 2, 5].erase 5 = [1, 3, 2, 5]

  • [1, 5, 3, 2, 5].erase 6 = [1, 5, 3, 2, 5]

🔗定义
List.eraseTR.{u_1} {α : Type u_1} [BEq α] (l : List α) (a : α) : List α
List.eraseTR.{u_1} {α : Type u_1} [BEq α] (l : List α) (a : α) : List α

删除第一次出现的 a,搜索范围为 l。如果 a 未出现在 l 中,则返回未修改的列表。

O(|l|)

这是 List.erase 的尾递归版本,用于运行时代码。

示例:

  • [1, 5, 3, 2, 5].eraseTR 5 = [1, 3, 2, 5]

  • [1, 5, 3, 2, 5].eraseTR 6 = [1, 5, 3, 2, 5]

🔗定义
List.eraseDups.{u_1} {α : Type u_1} [BEq α] (as : List α) : List α
List.eraseDups.{u_1} {α : Type u_1} [BEq α] (as : List α) : List α

删除列表中的重复元素,保留第一次出现的重复元素。

O(|l|^2)

示例:

  • [1, 3, 2, 2, 3, 5].eraseDups = [1, 3, 2, 5]

  • ["red", "green", "green", "blue"].eraseDups = ["red", "green", "blue"]

🔗定义
List.eraseIdx.{u} {α : Type u} (l : List α) (i : Nat) : List α
List.eraseIdx.{u} {α : Type u} (l : List α) (i : Nat) : List α

删除指定索引处的元素。如果索引越界,则列表将不加修改地返回。

O(i)

示例:

  • [0, 1, 2, 3, 4].eraseIdx 0 = [1, 2, 3, 4]

  • [0, 1, 2, 3, 4].eraseIdx 1 = [0, 2, 3, 4]

  • [0, 1, 2, 3, 4].eraseIdx 5 = [0, 1, 2, 3, 4]

🔗定义
List.eraseIdxTR.{u_1} {α : Type u_1} (l : List α) (n : Nat) : List α
List.eraseIdxTR.{u_1} {α : Type u_1} (l : List α) (n : Nat) : List α

删除指定索引处的元素。如果索引越界,则列表将不加修改地返回。

O(i)

这是 List.eraseIdx 的尾递归版本,在运行时使用。

示例:

🔗定义
List.eraseP.{u} {α : Type u} (p : α Bool) : List α List α
List.eraseP.{u} {α : Type u} (p : α Bool) : List α List α

删除 p 返回 true 的列表的第一个元素。如果没有元素满足 p,则列表原样返回。

示例:

  • [2, 1, 2, 1, 3, 4].eraseP (· < 2) = [2, 2, 1, 3, 4]

  • [2, 1, 2, 1, 3, 4].eraseP (· > 2) = [2, 1, 2, 1, 4]

  • [2, 1, 2, 1, 3, 4].eraseP (· > 8) = [2, 1, 2, 1, 3, 4]

🔗定义
List.erasePTR.{u_1} {α : Type u_1} (p : α Bool) (l : List α) : List α
List.erasePTR.{u_1} {α : Type u_1} (p : α Bool) (l : List α) : List α

删除 p 返回 true 的列表的第一个元素。如果没有元素满足 p,则列表原样返回。

这是 eraseP 的尾递归版本,在运行时使用。

示例:

  • [2, 1, 2, 1, 3, 4].erasePTR (· < 2) = [2, 2, 1, 3, 4]

  • [2, 1, 2, 1, 3, 4].erasePTR (· > 2) = [2, 1, 2, 1, 4]

  • [2, 1, 2, 1, 3, 4].erasePTR (· > 8) = [2, 1, 2, 1, 3, 4]

🔗定义
List.eraseReps.{u_1} {α : Type u_1} [BEq α] (as : List α) : List α
List.eraseReps.{u_1} {α : Type u_1} [BEq α] (as : List α) : List α

擦除重复的元素,保留每次运行的第一个元素。

O(|l|)

例子:

  • [1, 3, 2, 2, 2, 3, 3, 5].eraseReps = [1, 3, 2, 3, 5]

🔗定义
List.extract.{u} {α : Type u} (l : List α) (start : Nat := 0) (stop : Nat := l.length) : List α
List.extract.{u} {α : Type u} (l : List α) (start : Nat := 0) (stop : Nat := l.length) : List α

返回 l 从索引 start(包含)到 stop(不包含)的切片。

示例:

  • [0, 1, 2, 3, 4, 5].extract 1 2 = [1]

  • [0, 1, 2, 3, 4, 5].extract 2 2 = []

  • [0, 1, 2, 3, 4, 5].extract 2 4 = [2, 3]

  • [0, 1, 2, 3, 4, 5].extract 2 = [2, 3, 4, 5]

  • [0, 1, 2, 3, 4, 5].extract (stop := 2) = [0, 1]

🔗定义
List.removeAll.{u} {α : Type u} [BEq α] (xs ys : List α) : List α
List.removeAll.{u} {α : Type u} [BEq α] (xs ys : List α) : List α

删除 xs 中也存在于 ys 的所有元素。

O(|xs| * |ys|)

示例:

  • [1, 1, 5, 1, 2, 4, 5].removeAll [1, 2, 2] = [5, 4, 5]

  • [1, 2, 3, 2].removeAll [] = [1, 2, 3, 2]

  • [1, 2, 3, 2].removeAll [3] = [1, 2, 2]

🔗定义
List.replace.{u} {α : Type u} [BEq α] (l : List α) (a b : α) : List α
List.replace.{u} {α : Type u} [BEq α] (l : List α) (a b : α) : List α

将列表 l 中等于 a 的第一个元素替换为 b。如果没有元素等于 a,则列表原样返回。

O(|l|)

示例:

  • [1, 4, 2, 3, 3, 7].replace 3 6 = [1, 4, 2, 6, 3, 7]

  • [1, 4, 2, 3, 3, 7].replace 5 6 = [1, 4, 2, 3, 3, 7]

🔗定义
List.replaceTR.{u_1} {α : Type u_1} [BEq α] (l : List α) (b c : α) : List α
List.replaceTR.{u_1} {α : Type u_1} [BEq α] (l : List α) (b c : α) : List α

将列表 l 中等于 a 的第一个元素替换为 b。如果没有元素等于 a,则列表原样返回。

O(|l|)。这是运行时代码中使用的 List.replace 的尾递归版本。

示例:

  • [1, 4, 2, 3, 3, 7].replaceTR 3 6 = [1, 4, 2, 6, 3, 7]

  • [1, 4, 2, 3, 3, 7].replaceTR 5 6 = [1, 4, 2, 3, 3, 7]

🔗定义
List.reverse.{u} {α : Type u} (as : List α) : List α
List.reverse.{u} {α : Type u} (as : List α) : List α

反转列表。

O(|as|)

由于 Lean 编译器实现的“功能到位”优化,当该函数对输入列表的引用未共享时,它不会分配新列表:它只是遍历链表并反转所有节点指针。

示例:

🔗定义
List.flatten.{u_1} {α : Type u_1} : List (List α) List α
List.flatten.{u_1} {α : Type u_1} : List (List α) List α

将列表列表连接成单个列表,保留元素的顺序。

O(|flatten L|)

示例:

  • [["a"], ["b", "c"]].flatten = ["a", "b", "c"]

  • [["a"], [], ["b", "c"], ["d", "e", "f"]].flatten = ["a", "b", "c", "d", "e", "f"]

🔗定义
List.flattenTR.{u_1} {α : Type u_1} (l : List (List α)) : List α
List.flattenTR.{u_1} {α : Type u_1} (l : List (List α)) : List α

将列表列表连接成单个列表,保留元素的顺序。

O(|flatten L|)。这是 List.flatten 的尾递归版本,用于运行时代码。

示例:

  • [["a"], ["b", "c"]].flattenTR = ["a", "b", "c"]

  • [["a"], [], ["b", "c"], ["d", "e", "f"]].flattenTR = ["a", "b", "c", "d", "e", "f"]

🔗定义
List.rotateLeft.{u} {α : Type u} (xs : List α) (i : Nat := 1) : List α
List.rotateLeft.{u} {α : Type u} (xs : List α) (i : Nat := 1) : List α

xs 的元素向左旋转,将 i % xs.length 元素从列表的开头移动到结尾。

O(|xs|)

示例:

🔗定义
List.rotateRight.{u} {α : Type u} (xs : List α) (i : Nat := 1) : List α
List.rotateRight.{u} {α : Type u} (xs : List α) (i : Nat := 1) : List α

xs 的元素向右旋转,将 i % xs.length 元素从列表末尾移动到开头。

旋转后,xs[n] 处的元素位于索引 (i + n) % l.length 处。 O(|xs|)

示例:

🔗定义
List.leftpad.{u} {α : Type u} (n : Nat) (a : α) (l : List α) : List α
List.leftpad.{u} {α : Type u} (n : Nat) (a : α) (l : List α) : List α

在左侧填充 l : List α,并重复出现 a : α,直到其长度为 n。如果 l 已至少具有 n 元素,则返回未修改的元素。

示例:

  • [1, 2, 3].leftpad 5 0 = [0, 0, 1, 2, 3]

  • ["red", "green", "blue"].leftpad 4 "blank" = ["blank", "red", "green", "blue"]

  • ["red", "green", "blue"].leftpad 3 "blank" = ["red", "green", "blue"]

  • ["red", "green", "blue"].leftpad 1 "blank" = ["red", "green", "blue"]

🔗定义
List.leftpadTR.{u} {α : Type u} (n : Nat) (a : α) (l : List α) : List α
List.leftpadTR.{u} {α : Type u} (n : Nat) (a : α) (l : List α) : List α

在左侧填充 l : List α,并重复出现 a : α,直到其长度为 n。如果 l 已至少具有 n 元素,则返回未修改的元素。

这是 List.leftpad 的尾递归版本,在运行时使用。

示例:

  • [1, 2, 3].leftPadTR 5 0 = [0, 0, 1, 2, 3]

  • ["red", "green", "blue"].leftPadTR 4 "blank" = ["blank", "red", "green", "blue"]

  • ["red", "green", "blue"].leftPadTR 3 "blank" = ["red", "green", "blue"]

  • ["red", "green", "blue"].leftPadTR 1 "blank" = ["red", "green", "blue"]

🔗定义
List.rightpad.{u} {α : Type u} (n : Nat) (a : α) (l : List α) : List α
List.rightpad.{u} {α : Type u} (n : Nat) (a : α) (l : List α) : List α

在右侧填充 l : List α,并重复出现 a : α,直到其长度为 n。如果 l 已至少具有 n 元素,则返回未修改的元素。

示例:

  • [1, 2, 3].rightpad 5 0 = [1, 2, 3, 0, 0]

  • ["red", "green", "blue"].rightpad 4 "blank" = ["red", "green", "blue", "blank"]

  • ["red", "green", "blue"].rightpad 3 "blank" = ["red", "green", "blue"]

  • ["red", "green", "blue"].rightpad 1 "blank" = ["red", "green", "blue"]

20.15.3.8.1. 插入🔗

🔗定义
List.insert.{u} {α : Type u} [BEq α] (a : α) (l : List α) : List α
List.insert.{u} {α : Type u} [BEq α] (a : α) (l : List α) : List α

将一个元素插入到列表中,且不重复。

如果该元素存在于列表中,则返回未修改的列表。否则,新元素将插入到列表的头部。

示例:

  • [1, 2, 3].insert 0 = [0, 1, 2, 3]

  • [1, 2, 3].insert 4 = [4, 1, 2, 3]

  • [1, 2, 3].insert 2 = [1, 2, 3]

🔗定义
List.insertIdx.{u} {α : Type u} (xs : List α) (i : Nat) (a : α) : List α
List.insertIdx.{u} {α : Type u} (xs : List α) (i : Nat) (a : α) : List α

将元素插入列表中指定索引处。如果索引大于列表的长度,则列表将不加修改地返回。

换句话说,新元素被插入到列表 l 中前 i 个元素之后;此列表即 l

示例:

  • ["tues", "thur", "sat"].insertIdx 1 "wed" = ["tues", "wed", "thur", "sat"]

  • ["tues", "thur", "sat"].insertIdx 2 "wed" = ["tues", "thur", "wed", "sat"]

  • ["tues", "thur", "sat"].insertIdx 3 "wed" = ["tues", "thur", "sat", "wed"]

  • ["tues", "thur", "sat"].insertIdx 4 "wed" = ["tues", "thur", "sat"]

🔗定义
List.insertIdxTR.{u_1} {α : Type u_1} (l : List α) (n : Nat) (a : α) : List α
List.insertIdxTR.{u_1} {α : Type u_1} (l : List α) (n : Nat) (a : α) : List α

将元素插入列表中指定索引处。如果索引大于列表的长度,则列表将不加修改地返回。

换句话说,新元素被插入到列表 l 中前 i 个元素之后;此列表即 l

这是 List.insertIdx 的尾递归版本,在运行时使用。

示例:

  • ["tues", "thur", "sat"].insertIdxTR 1 "wed" = ["tues", "wed", "thur", "sat"]

  • ["tues", "thur", "sat"].insertIdxTR 2 "wed" = ["tues", "thur", "wed", "sat"]

  • ["tues", "thur", "sat"].insertIdxTR 3 "wed" = ["tues", "thur", "sat", "wed"]

  • ["tues", "thur", "sat"].insertIdxTR 4 "wed" = ["tues", "thur", "sat"]

🔗定义
List.intersperse.{u} {α : Type u} (sep : α) (l : List α) : List α
List.intersperse.{u} {α : Type u} (sep : α) (l : List α) : List α

lsep 的元素交替。

O(|l|)

List.intercalate 是一个类似的函数,它将分隔符列表与列表列表的元素交替。

示例:

🔗定义
List.intersperseTR.{u} {α : Type u} (sep : α) (l : List α) : List α
List.intersperseTR.{u} {α : Type u} (sep : α) (l : List α) : List α

lsep 的元素交替。

O(|l|)

这是 List.intersperse 的尾递归版本,在运行时使用。

示例:

🔗定义
List.intercalate.{u} {α : Type u} (sep : List α) (xs : List (List α)) : List α
List.intercalate.{u} {α : Type u} (sep : List α) (xs : List (List α)) : List α

xs 中的列表与分隔符 sep 交替,并附加它们。结果列表被展平。

O(|xs|)

List.intersperse 是一个类似的函数,它将分隔符元素与列表的元素交替。

示例:

🔗定义
List.intercalateTR.{u_1} {α : Type u_1} (sep : List α) (xs : List (List α)) : List α
List.intercalateTR.{u_1} {α : Type u_1} (sep : List α) (xs : List (List α)) : List α

xs 中的列表与分隔符 sep 交替。

这是运行时使用的 List.intercalate 的尾递归版本。

示例:

20.15.3.9. 排序🔗

🔗定义
List.mergeSort.{u_1} {α : Type u_1} (xs : List α) (le : α α Bool := by exact fun a b => a b) : List α
List.mergeSort.{u_1} {α : Type u_1} (xs : List α) (le : α α Bool := by exact fun a b => a b) : List α

稳定的归并排序。

该函数是一个简化的实现,旨在易于推理,而不是 为了效率。特别是,它使用非尾递归 List.merge 函数并遍历 不必要地列出。

它在运行时被已被证明等效的高效实现所取代。

🔗定义
List.merge.{u_1} {α : Type u_1} (xs ys : List α) (le : α α Bool := by exact fun a b => a b) : List α
List.merge.{u_1} {α : Type u_1} (xs ys : List α) (le : α α Bool := by exact fun a b => a b) : List α

合并两个列表,如果两者都是,则使用 le 选择结果列表的第一个元素 非空。

如果两个输入列表都根据 le 排序,则结果列表也根据 至 leO(|xs| + |ys|)

此实现不是尾递归的,但它在运行时被经过验证的等效实现替换 尾递归合并。

20.15.3.10. 迭代🔗

🔗定义
List.iter.{w} {α : Type w} (l : List α) : Std.Iter α
List.iter.{w} {α : Type w} (l : List α) : Std.Iter α

返回给定列表的有限迭代器。 迭代器按顺序生成列表的元素,然后终止。

该迭代器的单子版本是 List.iterM

终止属性:

  • Finite 实例:始终

  • Productive 实例:始终

🔗定义
List.iterM.{w, w'} {α : Type w} (l : List α) (m : Type w Type w') [Pure m] : Std.IterM m α
List.iterM.{w, w'} {α : Type w} (l : List α) (m : Type w Type w') [Pure m] : Std.IterM m α

返回给定列表的有限迭代器。 迭代器按顺序生成列表的元素,然后终止。

该迭代器的非单子版本是 List.iter

终止属性:

  • Finite 实例:始终

  • Productive 实例:始终

🔗定义
List.forA.{u, v, w} {m : Type u Type v} [Applicative m] {α : Type w} (as : List α) (f : α m PUnit) : m PUnit
List.forA.{u, v, w} {m : Type u Type v} [Applicative m] {α : Type w} (as : List α) (f : α m PUnit) : m PUnit

按顺序将应用操作 f 应用于列表中的每个元素。

如果 m 也是 Monad,那么使用 List.forM 会更高效。

List.mapA 是一个收集结果的变体。

🔗定义
List.forM.{u, v, w} {m : Type u Type v} [Monad m] {α : Type w} (as : List α) (f : α m PUnit) : m PUnit
List.forM.{u, v, w} {m : Type u Type v} [Monad m] {α : Type w} (as : List α) (f : α m PUnit) : m PUnit

按顺序将一元操作 f 应用于列表中的每个元素。

List.mapM 是一个收集结果的变体。 List.forA 是一个适用于任何 Applicative

🔗定义
List.firstM.{u, v, w} {m : Type u Type v} [Alternative m] {α : Type w} {β : Type u} (f : α m β) : List α m β
List.firstM.{u, v, w} {m : Type u Type v} [Alternative m] {α : Type w} {β : Type u} (f : α m β) : List α m β

f 映射到列表并使用 <|> 收集结果。列表末尾的结果是 failure

示例:

🔗定义
List.sum.{u_1} {α : Type u_1} [Add α] [Zero α] : List α α
List.sum.{u_1} {α : Type u_1} [Add α] [Zero α] : List α α

计算列表元素的总和。

示例:

  • [a, b, c].sum = a + (b + (c + 0))

  • [1, 2, 5].sum = 8

20.15.3.10.1. 折叠🔗

折叠是使用某个函数将列表元素组合起来的运算。 根据函数调用的嵌套方式,它们分为两类:

左折叠

左折叠从列表头开始向末尾依次组合元素。 列表头会先与初始值组合,该结果再与下一个值组合,依此类推。

右折叠

右折叠从列表尾开始向开头组合元素,就像把每个 cons 构造子替换成一次对组合函数的调用,并把 nil 替换成初始值一样。

-M 后缀的单子折叠允许组合函数使用某个 单子 中的效应,这也可能包括提前终止折叠。

🔗定义
List.foldl.{u, v} {α : Type u} {β : Type v} (f : α β α) (init : α) : List β α
List.foldl.{u, v} {α : Type u} {β : Type v} (f : α β α) (init : α) : List β α

将函数从左侧折叠到列表上,累积以 init 开头的值。的 累积值使用 f 按顺序与列表中的每个元素组合。

示例:

  • [a, b, c].foldl f z = f (f (f z a) b) c

  • [1, 2, 3].foldl (· ++ toString ·) "" = "123"

  • [1, 2, 3].foldl (s!"({·} {·})") "" = "((( 1) 2) 3)"

🔗定义
List.foldlM.{u, v, w} {m : Type u Type v} [Monad m] {s : Type u} {α : Type w} (f : s α m s) (init : s) : List α m s
List.foldlM.{u, v, w} {m : Type u Type v} [Monad m] {s : Type u} {α : Type w} (f : s α m s) (init : s) : List α m s

将一元函数从左侧折叠到列表上,累积以 init 开头的值。的 累积值使用 f 按顺序与列表中的每个元素组合。

示例:

example [Monad m] (f : α → β → m α) :
    List.foldlM (m := m) f x₀ [a, b, c] = (do
      let x₁ ← f x₀ a
      let x₂ ← f x₁ b
      let x₃ ← f x₂ c
      pure x₃)
  := by rfl
🔗定义
List.foldlRecOn.{u_1, u_2, u_3} {β : Type u_1} {α : Type u_2} {motive : β Sort u_3} (l : List α) (op : β α β) {b : β} : motive b ((b : β) motive b (a : α) a l motive (op b a)) motive (List.foldl op b l)
List.foldlRecOn.{u_1, u_2, u_3} {β : Type u_1} {α : Type u_2} {motive : β Sort u_3} (l : List α) (op : β α β) {b : β} : motive b ((b : β) motive b (a : α) a l motive (op b a)) motive (List.foldl op b l)

通过建立对初始数据成立且被折叠操作保持的不变量,证明有关 List.foldl 结果的命题。

此段说明该操作的行为、边界条件及推荐用法。

示例:

example {xs : List Nat} : xs.foldl (· + ·) 1 > 0 := xs:List NatList.foldl (fun x1 x2 => x1 + x2) 1 xs > 0 xs:List Nat0 < 1xs:List Nat (b : Nat), 0 < b (a : Nat), a xs 0 < b + a xs:List Nat0 < 1 xs:List Nat0 < 1; All goals completed! 🐙 xs:List Nat (b : Nat), 0 < b (a : Nat), a xs 0 < b + a xs:List Nat (b : Nat), 0 < b (a : Nat), a xs 0 < b + a xs:List Natb✝:Nata✝²:0 < b✝a✝¹:Nata✝:a✝¹ xs0 < b✝ + a✝¹; All goals completed! 🐙
🔗定义
List.foldr.{u, v} {α : Type u} {β : Type v} (f : α β β) (init : β) (l : List α) : β
List.foldr.{u, v} {α : Type u} {β : Type v} (f : α β β) (init : β) (l : List α) : β

从右侧折叠列表,以 init 为初值,并用 f 按逆序把每个元素与累积值结合。

运行时实现具有所述优化与复杂度特性。(相关项:O(|l|)List.foldrTR。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:[a, b, c].foldr f init = f a (f b (f c init))。)

  • 示例见所列代码。(相关项:[1, 2, 3].foldr (toString · ++ ·) "" = "123"。)

  • 示例见所列代码。(相关项:[1, 2, 3].foldr (s!"({·} {·})") "!" = "(1 (2 (3 !)))"。)

🔗定义
List.foldrM.{u, v, w} {m : Type u Type v} [Monad m] {s : Type u} {α : Type w} (f : α s m s) (init : s) (l : List α) : m s
List.foldrM.{u, v, w} {m : Type u Type v} [Monad m] {s : Type u} {α : Type w} (f : α s m s) (init : s) (l : List α) : m s

从右侧用单子函数折叠列表,以 init 为初值,并用 f 按逆序把每个元素与累积值结合。

示例:

example [Monad m] (f : α → β → m β) :
  List.foldrM (m := m) f x₀ [a, b, c] = (do
    let x₁ ← f c x₀
    let x₂ ← f b x₁
    let x₃ ← f a x₂
    pure x₃)
  := by rfl
🔗定义
List.foldrRecOn.{u_1, u_2, u_3} {β : Type u_1} {α : Type u_2} {motive : β Sort u_3} (l : List α) (op : α β β) {b : β} : motive b ((b : β) motive b (a : α) a l motive (op a b)) motive (List.foldr op b l)
List.foldrRecOn.{u_1, u_2, u_3} {β : Type u_1} {α : Type u_2} {motive : β Sort u_3} (l : List α) (op : α β β) {b : β} : motive b ((b : β) motive b (a : α) a l motive (op a b)) motive (List.foldr op b l)

通过建立对初始数据成立且被折叠操作保持的不变量,证明有关 List.foldr 结果的命题。

此段说明该操作的行为、边界条件及推荐用法。

示例:

example {xs : List Nat} : xs.foldr (· + ·) 1 > 0 := xs:List NatList.foldr (fun x1 x2 => x1 + x2) 1 xs > 0 xs:List Nat0 < 1xs:List Nat (b : Nat), 0 < b (a : Nat), a xs 0 < a + b xs:List Nat0 < 1 xs:List Nat0 < 1; All goals completed! 🐙 xs:List Nat (b : Nat), 0 < b (a : Nat), a xs 0 < a + b xs:List Nat (b : Nat), 0 < b (a : Nat), a xs 0 < a + b xs:List Natb✝:Nata✝²:0 < b✝a✝¹:Nata✝:a✝¹ xs0 < a✝¹ + b✝; All goals completed! 🐙
🔗定义
List.foldrTR.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : α β β) (init : β) (l : List α) : β
List.foldrTR.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : α β β) (init : β) (l : List α) : β

从右侧折叠列表,以 init 为初值,并用 f 按逆序把每个元素与累积值结合。

这是相应函数的尾递归版本,并在运行时代码中使用。(相关项:O(|l|)List.foldr。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:[a, b, c].foldrTR f init = f a (f b (f c init))。)

  • 示例见所列代码。(相关项:[1, 2, 3].foldrTR (toString · ++ ·) "" = "123"。)

  • 示例见所列代码。(相关项:[1, 2, 3].foldrTR (s!"({·} {·})") "!" = "(1 (2 (3 !)))"。)

20.15.3.11. 转换🔗

🔗定义
List.map.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : α β) (l : List α) : List β
List.map.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : α β) (l : List α) : List β

将函数应用于列表的每个元素,返回结果值列表。

O(|l|)

示例:

  • [a, b, c].map f = [f a, f b, f c]

  • [].map Nat.succ = []

  • ["one", "two", "three"].map (·.length) = [3, 3, 5]

  • ["one", "two", "three"].map (·.reverse) = ["eno", "owt", "eerht"]

🔗定义
List.mapTR.{u, v} {α : Type u} {β : Type v} (f : α β) (as : List α) : List β
List.mapTR.{u, v} {α : Type u} {β : Type v} (f : α β) (as : List α) : List β

将函数应用于列表的每个元素,返回结果值列表。

O(|l|)。这是 List.map 的尾递归变体,在运行时代码中使用。

示例:

  • [a, b, c].mapTR f = [f a, f b, f c]

  • [].mapTR Nat.succ = []

  • ["one", "two", "three"].mapTR (·.length) = [3, 3, 5]

  • ["one", "two", "three"].mapTR (·.reverse) = ["eno", "owt", "eerht"]

🔗定义
List.mapM.{u, v, w} {m : Type u Type v} [Monad m] {α : Type w} {β : Type u} (f : α m β) (as : List α) : m (List β)
List.mapM.{u, v, w} {m : Type u Type v} [Monad m] {α : Type w} {β : Type u} (f : α m β) (as : List α) : m (List β)

将单子操作 f 从左到右应用于列表中的每个元素,并返回结果列表。

这个实现是尾递归的。 List.mapM' 是一种非尾递归变体,可能更方便推理。 List.forM 是丢弃结果的变体,List.mapA 是与 Applicative 一起使用的变体。

🔗定义
List.mapM'.{u_1, u_2, u_3} {m : Type u_1 Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (f : α m β) : List α m (List β)
List.mapM'.{u_1, u_2, u_3} {m : Type u_1 Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (f : α m β) : List α m (List β)

从左到右对列表中的每个元素应用一元操作 f,并返回结果列表。

这是 List.mapM 的非尾递归变体,更容易推理。它不能用作主定义并被尾递归版本替换,因为只有当 mLawfulMonad 时才能证明它们相等。

🔗定义
List.mapA.{u, v, w} {m : Type u Type v} [Applicative m] {α : Type w} {β : Type u} (f : α m β) : List α m (List β)
List.mapA.{u, v, w} {m : Type u Type v} [Applicative m] {α : Type w} {β : Type u} (f : α m β) : List α m (List β)

从左到右对列表中的每个元素应用应用操作 f,并返回结果列表。

如果 m 也是 Monad,则使用 mapM 会更高效。

请参阅 List.forA 了解丢弃结果的变体。请参阅 List.mapM 了解与 Monad 配合使用的变体。

此函数不是尾递归的,因此它可能会因长列表上的堆栈溢出而失败。

🔗定义
List.mapFinIdx.{u_1, u_2} {α : Type u_1} {β : Type u_2} (as : List α) (f : (i : Nat) α i < as.length β) : List β
List.mapFinIdx.{u_1, u_2} {α : Type u_1} {β : Type u_2} (as : List α) (f : (i : Nat) α i < as.length β) : List β

将函数应用于列表中的每个元素以及找到该元素的索引,返回结果列表。除了索引之外,该函数还提供了索引有效的证明。

List.mapIdx 是一个变体,它不向函数提供索引有效的证据。

🔗定义
List.mapFinIdxM.{u_1, u_2, u_3} {m : Type u_1 Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (as : List α) (f : (i : Nat) α i < as.length m β) : m (List β)
List.mapFinIdxM.{u_1, u_2, u_3} {m : Type u_1 Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (as : List α) (f : (i : Nat) α i < as.length m β) : m (List β)

将一元函数应用于列表中的每个元素以及找到该元素的索引,返回结果列表。除了索引之外,该函数还提供了索引有效的证明。

List.mapIdxM 是一个变体,它不向函数提供索引有效的证据。

🔗定义
List.mapIdx.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : Nat α β) (as : List α) : List β
List.mapIdx.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : Nat α β) (as : List α) : List β

将函数应用于列表中的每个元素以及找到该元素的索引,返回结果列表。

List.mapFinIdx 是一个变体,它另外为该函数提供索引有效的证明。

🔗定义
List.mapIdxM.{u_1, u_2, u_3} {m : Type u_1 Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (f : Nat α m β) (as : List α) : m (List β)
List.mapIdxM.{u_1, u_2, u_3} {m : Type u_1 Type u_2} {α : Type u_3} {β : Type u_1} [Monad m] (f : Nat α m β) (as : List α) : m (List β)

将一元函数应用于列表的每个元素以及找到该元素的索引,返回结果列表。

List.mapFinIdxM 是一个变体,它另外为该函数提供索引有效的证明。

🔗定义
List.mapMono.{u_1} {α : Type u_1} (as : List α) (f : α α) : List α
List.mapMono.{u_1} {α : Type u_1} (as : List α) (f : α α) : List α

将函数应用于列表的每个元素,返回结果列表。该函数是单态的:要求返回相同类型的值。内部实现使用指针相等,并且如果每个函数调用的结果与其参数指针相等,则不会分配新列表。

出于验证目的,List.mapMono = List.map

🔗定义
List.mapMonoM.{u_1, u_2} {m : Type u_1 Type u_2} {α : Type u_1} [Monad m] (as : List α) (f : α m α) : m (List α)
List.mapMonoM.{u_1, u_2} {m : Type u_1 Type u_2} {α : Type u_1} [Monad m] (as : List α) (f : α m α) : m (List α)

将一元函数应用于列表的每个元素,返回结果列表。该函数是单态的:要求返回相同类型的值。内部实现使用指针相等,并且如果每个函数调用的结果与其参数指针相等,则不会分配新列表。

🔗定义
List.flatMap.{u, v} {α : Type u} {β : Type v} (b : α List β) (as : List α) : List β
List.flatMap.{u, v} {α : Type u} {β : Type v} (b : α List β) (as : List α) : List β

应用一个函数,将列表返回到列表的每个元素,并连接结果列表。

示例:

  • [2, 3, 2].flatMap List.range = [0, 1, 0, 1, 2, 0, 1]

  • ["red", "blue"].flatMap String.toList = ['r', 'e', 'd', 'b', 'l', 'u', 'e']

🔗定义
List.flatMapTR.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : α List β) (as : List α) : List β
List.flatMapTR.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : α List β) (as : List α) : List β

应用一个函数,将列表返回到列表的每个元素,并连接结果列表。

这是运行时使用的 List.flatMap 的尾递归版本。

示例:

🔗定义
List.flatMapM.{u, v, w} {m : Type u Type v} [Monad m] {α : Type w} {β : Type u} (f : α m (List β)) (as : List α) : m (List β)
List.flatMapM.{u, v, w} {m : Type u Type v} [Monad m] {α : Type w} {β : Type u} (f : α m (List β)) (as : List α) : m (List β)

应用一个单子函数,该函数从左到右将列表返回到列表中的每个元素,并连接结果列表。

🔗定义
List.zip.{u, v} {α : Type u} {β : Type v} : List α List β List (α × β)
List.zip.{u, v} {α : Type u} {β : Type v} : List α List β List (α × β)

将两个列表组合成一个对列表,其中第一个和第二个组件是每个列表的对应元素。结果列表是输入列表中较短者的长度。

O(min |xs| |ys|)

示例:

  • ["Mon", "Tue", "Wed"].zip [1, 2, 3] = [("Mon", 1), ("Tue", 2), ("Wed", 3)]

  • ["Mon", "Tue", "Wed"].zip [1, 2] = [("Mon", 1), ("Tue", 2)]

  • [x₁, x₂, x₃].zip [y₁, y₂, y₃, y₄] = [(x₁, y₁), (x₂, y₂), (x₃, y₃)]

🔗定义
List.zipIdx.{u} {α : Type u} (l : List α) (n : Nat := 0) : List (α × Nat)
List.zipIdx.{u} {α : Type u} (l : List α) (n : Nat := 0) : List (α × Nat)

将列表的每个元素与其索引配对,可以选择从 0 以外的索引开始。

O(|l|)

示例:

  • [a, b, c].zipIdx = [(a, 0), (b, 1), (c, 2)]

  • [a, b, c].zipIdx 5 = [(a, 5), (b, 6), (c, 7)]

🔗定义
List.zipIdxTR.{u_1} {α : Type u_1} (l : List α) (n : Nat := 0) : List (α × Nat)
List.zipIdxTR.{u_1} {α : Type u_1} (l : List α) (n : Nat := 0) : List (α × Nat)

将列表的每个元素与其索引配对,可以选择从 0 以外的索引开始。

O(|l|)。这是在运行时使用的 List.zipIdx 的尾递归版本。

示例:

  • [a, b, c].zipIdxTR = [(a, 0), (b, 1), (c, 2)]

  • [a, b, c].zipIdxTR 5 = [(a, 5), (b, 6), (c, 7)]

🔗定义
List.zipWith.{u, v, w} {α : Type u} {β : Type v} {γ : Type w} (f : α β γ) (xs : List α) (ys : List β) : List γ
List.zipWith.{u, v, w} {α : Type u} {β : Type v} {γ : Type w} (f : α β γ) (xs : List α) (ys : List β) : List γ

将函数应用于两个列表的相应元素,并在较短列表的末尾停止。

O(min |xs| |ys|)

示例:

  • [1, 2].zipWith (· + ·) [5, 6] = [6, 8]

  • [1, 2, 3].zipWith (· + ·) [5, 6, 10] = [6, 8, 13]

  • [].zipWith (· + ·) [5, 6] = []

  • [x₁, x₂, x₃].zipWith f [y₁, y₂, y₃, y₄] = [f x₁ y₁, f x₂ y₂, f x₃ y₃]

🔗定义
List.zipWithTR.{u_1, u_2, u_3} {α : Type u_1} {β : Type u_2} {γ : Type u_3} (f : α β γ) (as : List α) (bs : List β) : List γ
List.zipWithTR.{u_1, u_2, u_3} {α : Type u_1} {β : Type u_2} {γ : Type u_3} (f : α β γ) (as : List α) (bs : List β) : List γ

将函数应用于两个列表的相应元素,并在较短列表的末尾停止。

O(min |xs| |ys|)。这是在运行时使用的 List.zipWith 的尾递归版本。

示例:

  • [1, 2].zipWithTR (· + ·) [5, 6] = [6, 8]

  • [1, 2, 3].zipWithTR (· + ·) [5, 6, 10] = [6, 8, 13]

  • [].zipWithTR (· + ·) [5, 6] = []

  • [x₁, x₂, x₃].zipWithTR f [y₁, y₂, y₃, y₄] = [f x₁ y₁, f x₂ y₂, f x₃ y₃]

🔗定义
List.zipWithAll.{u, v, w} {α : Type u} {β : Type v} {γ : Type w} (f : Option α Option β γ) : List α List β List γ
List.zipWithAll.{u, v, w} {α : Type u} {β : Type v} {γ : Type w} (f : Option α Option β γ) : List α List β List γ

将函数应用于两个列表的相应元素,当两个列表中都没有更多元素时停止。如果一个列表比另一个列表短,则函数将通过 none 查找缺失的元素。

示例:

🔗定义
List.unzip.{u, v} {α : Type u} {β : Type v} (l : List (α × β)) : List α × List β
List.unzip.{u, v} {α : Type u} {β : Type v} (l : List (α × β)) : List α × List β

将成对列表分成两个列表,其中包含各自的第一和第二组件。

O(|l|)

示例:

  • [("Monday", 1), ("Tuesday", 2)].unzip = (["Monday", "Tuesday"], [1, 2])

  • [(x₁, y₁), (x₂, y₂), (x₃, y₃)].unzip = ([x₁, x₂, x₃], [y₁, y₂, y₃])

  • ([] : List (Nat × String)).unzip = (([], []) : List Nat × List String)

🔗定义
List.unzipTR.{u, v} {α : Type u} {β : Type v} (l : List (α × β)) : List α × List β
List.unzipTR.{u, v} {α : Type u} {β : Type v} (l : List (α × β)) : List α × List β

将成对列表分成两个列表,其中包含各自的第一和第二组件。

O(|l|)。这是在运行时使用的 List.unzip 的尾递归版本。

示例:

20.15.3.12. 过滤🔗

🔗定义
List.filter.{u} {α : Type u} (p : α Bool) (l : List α) : List α
List.filter.{u} {α : Type u} (p : α Bool) (l : List α) : List α

返回 l 中使 p 返回 true 的元素所组成的列表。

O(|l|).

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:[1, 2, 5, 2, 7, 7].filter (· > 2) = [5, 7, 7]。)

  • 示例见所列代码。(相关项:[1, 2, 5, 2, 7, 7].filter (fun _ => false) = []。)

  • 示例见所列代码。(相关项:[1, 2, 5, 2, 7, 7].filter (fun _ => true) = [1, 2, 5, 2, 7, 7]。)

🔗定义
List.filterTR.{u} {α : Type u} (p : α Bool) (as : List α) : List α
List.filterTR.{u} {α : Type u} (p : α Bool) (as : List α) : List α

返回 l 中使 p 返回 true 的元素所组成的列表。

这是相应函数的尾递归版本,并在运行时代码中使用。(相关项:O(|l|)List.filter。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:[1, 2, 5, 2, 7, 7].filterTR (· > 2) = [5, 7, 7]。)

  • 示例见所列代码。(相关项:[1, 2, 5, 2, 7, 7].filterTR (fun _ => false) = []。)

  • 示例见所列代码。(相关项:[1, 2, 5, 2, 7, 7].filterTR (fun _ => true) = * [1, 2, 5, 2, 7, 7]。)

🔗定义
List.filterM.{v} {m : Type Type v} [Monad m] {α : Type} (p : α m Bool) (as : List α) : m (List α)
List.filterM.{v} {m : Type Type v} [Monad m] {α : Type} (p : α m Bool) (as : List α) : m (List α)

从左到右依次把单子谓词 p 应用于列表中的每个元素,并返回使 p 返回 true 的元素。

O(|l|).

示例:

[1, 2, 2]Checking 1 Checking 2 Checking 5 Checking 2 Checking 7 Checking 7 #eval [1, 2, 5, 2, 7, 7].filterM fun x => do IO.println s!"Checking {x}" return x < 3 Checking 1 Checking 2 Checking 5 Checking 2 Checking 7 Checking 7[1, 2, 2]
🔗定义
List.filterRevM.{v} {m : Type Type v} [Monad m] {α : Type} (p : α m Bool) (as : List α) : m (List α)
List.filterRevM.{v} {m : Type Type v} [Monad m] {α : Type} (p : α m Bool) (as : List α) : m (List α)

从右到左逆序把单子谓词 p 应用于列表中的每个元素,并返回使 p 返回 true 的元素;结果仍保持输入顺序。

示例:

[1, 2, 2]Checking 7 Checking 7 Checking 2 Checking 5 Checking 2 Checking 1 #eval [1, 2, 5, 2, 7, 7].filterRevM fun x => do IO.println s!"Checking {x}" return x < 3 Checking 7 Checking 7 Checking 2 Checking 5 Checking 2 Checking 1[1, 2, 2]
🔗定义
List.filterMap.{u, v} {α : Type u} {β : Type v} (f : α Option β) : List α List β
List.filterMap.{u, v} {α : Type u} {β : Type v} (f : α Option β) : List α List β

把返回 Option 的函数应用于列表的每个元素,并收集所有非 none 值。

O(|l|).

示例:

[10, 14, 14]#eval [1, 2, 5, 2, 7, 7].filterMap fun x => if x > 2 then some (2 * x) else none [10, 14, 14]
🔗定义
List.filterMapTR.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : α Option β) (l : List α) : List β
List.filterMapTR.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : α Option β) (l : List α) : List β

把返回 Option 的函数应用于列表的每个元素,并收集所有非 none 值。

这是相应函数的尾递归版本,并在运行时代码中使用。(相关项:O(|l|)List.filterMap。)

示例:

[10, 14, 14]#eval [1, 2, 5, 2, 7, 7].filterMapTR fun x => if x > 2 then some (2 * x) else none [10, 14, 14]
🔗定义
List.filterMapM.{u, v, w} {m : Type u Type v} [Monad m] {α : Type w} {β : Type u} (f : α m (Option β)) (as : List α) : m (List β)
List.filterMapM.{u, v, w} {m : Type u Type v} [Monad m] {α : Type w} {β : Type u} (f : α m (Option β)) (as : List α) : m (List β)

把返回 Option 的单子函数应用于列表的每个元素,并收集所有非 none 值。

O(|l|).

示例:

[10, 14, 14]Examining 1 Examining 2 Examining 5 Examining 2 Examining 7 Examining 7 #eval [1, 2, 5, 2, 7, 7].filterMapM fun x => do IO.println s!"Examining {x}" if x > 2 then return some (2 * x) else return none Examining 1 Examining 2 Examining 5 Examining 2 Examining 7 Examining 7[10, 14, 14]

20.15.3.12.1. 分割🔗

🔗定义
List.take.{u} {α : Type u} (n : Nat) (xs : List α) : List α
List.take.{u} {α : Type u} (n : Nat) (xs : List α) : List α

提取前 nxs 元素;如果 n 大于 xs.length,则提取整个列表。

O(min n |xs|)

示例:

  • [a, b, c, d, e].take 0 = []

  • [a, b, c, d, e].take 3 = [a, b, c]

  • [a, b, c, d, e].take 6 = [a, b, c, d, e]

🔗定义
List.takeTR.{u_1} {α : Type u_1} (n : Nat) (l : List α) : List α
List.takeTR.{u_1} {α : Type u_1} (n : Nat) (l : List α) : List α

提取前 nxs 元素;如果 n 大于 xs.length,则提取整个列表。

O(min n |xs|)。这是运行时使用的 List.take 尾递归版本。

示例:

  • [a, b, c, d, e].takeTR 0 = []

  • [a, b, c, d, e].takeTR 3 = [a, b, c]

  • [a, b, c, d, e].takeTR 6 = [a, b, c, d, e]

🔗定义
List.takeWhile.{u} {α : Type u} (p : α Bool) (xs : List α) : List α
List.takeWhile.{u} {α : Type u} (p : α Bool) (xs : List α) : List α

返回 xsp 返回 true 的最长初始段。

O(|xs|)

示例:

🔗定义
List.takeWhileTR.{u_1} {α : Type u_1} (p : α Bool) (l : List α) : List α
List.takeWhileTR.{u_1} {α : Type u_1} (p : α Bool) (l : List α) : List α

返回 xsp 返回 true 的最长初始段。

O(|xs|)。这是 List.take 的尾递归版本,在运行时使用。

示例:

🔗定义
List.drop.{u} {α : Type u} (n : Nat) (xs : List α) : List α
List.drop.{u} {α : Type u} (n : Nat) (xs : List α) : List α

移除前 n 个列表 xs 的元素。如果 n 大于列表长度,则返回空列表。

O(min n |xs|)

示例:

  • [0, 1, 2, 3, 4].drop 0 = [0, 1, 2, 3, 4]

  • [0, 1, 2, 3, 4].drop 3 = [3, 4]

  • [0, 1, 2, 3, 4].drop 6 = []

🔗定义
List.dropWhile.{u} {α : Type u} (p : α Bool) : List α List α
List.dropWhile.{u} {α : Type u} (p : α Bool) : List α List α

删除 p 返回 true 的列表的最长前缀。

元素将从列表中删除,直到遇到 p 返回 false 的元素为止。返回该元素和列表的其余部分。

O(|l|)

示例:

  • [1, 3, 2, 4, 2, 7, 4].dropWhile (· < 4) = [4, 2, 7, 4]

  • [8, 3, 2, 4, 2, 7, 4].dropWhile (· < 4) = [8, 3, 2, 4, 2, 7, 4]

  • [8, 3, 2, 4, 2, 7, 4].dropWhile (· < 100) = []

🔗定义
List.dropLast.{u_1} {α : Type u_1} : List α List α
List.dropLast.{u_1} {α : Type u_1} : List α List α

删除列表的最后一个元素(如果存在)。

示例:

🔗定义
List.dropLastTR.{u_1} {α : Type u_1} (l : List α) : List α
List.dropLastTR.{u_1} {α : Type u_1} (l : List α) : List α

删除列表的最后一个元素(如果存在)。

这是 List.dropLast 的尾递归版本,在运行时使用。

示例:

🔗定义
List.splitAt.{u} {α : Type u} (n : Nat) (l : List α) : List α × List α
List.splitAt.{u} {α : Type u} (n : Nat) (l : List α) : List α × List α

在索引处拆分列表,结果将前 nl 的元素与剩余元素配对。

如果 n 大于 l 的长度,则结果对由 l 和空列表组成。List.splitAt 等价于组合使用 List.takeList.drop,但效率更高。

示例:

  • ["red", "green", "blue"].splitAt 2 = (["red", "green"], ["blue"])

  • ["red", "green", "blue"].splitAt 3 = (["red", "green", "blue], [])

  • ["red", "green", "blue"].splitAt 4 = (["red", "green", "blue], [])

🔗定义
List.span.{u} {α : Type u} (p : α Bool) (as : List α) : List α × List α
List.span.{u} {α : Type u} (p : α Bool) (as : List α) : List α × List α

将列表拆分为最长的初始段,p 返回 true,并与列表的其余部分配对。

O(|l|)

示例:

  • [6, 8, 9, 5, 2, 9].span (· > 5) = ([6, 8, 9], [5, 2, 9])

  • [6, 8, 9, 5, 2, 9].span (· > 10) = ([], [6, 8, 9, 5, 2, 9])

  • [6, 8, 9, 5, 2, 9].span (· > 0) = ([6, 8, 9, 5, 2, 9], [])

🔗定义
List.splitBy.{u} {α : Type u} (R : α α Bool) : List α List (List α)
List.splitBy.{u} {α : Type u} (R : α α Bool) : List α List (List α)

将列表拆分为最长的段,其中每对相邻元素通过 R 相关。

O(|l|)

示例:

  • [1, 1, 2, 2, 2, 3, 2].splitBy (· == ·) = [[1, 1], [2, 2, 2], [3], [2]]

  • [1, 2, 5, 4, 5, 1, 4].splitBy (· < ·) = [[1, 2, 5], [4, 5], [1, 4]]

  • [1, 2, 5, 4, 5, 1, 4].splitBy (fun _ _ => true) = [[1, 2, 5, 4, 5, 1, 4]]

  • [1, 2, 5, 4, 5, 1, 4].splitBy (fun _ _ => false) = [[1], [2], [5], [4], [5], [1], [4]]

🔗定义
List.partition.{u} {α : Type u} (p : α Bool) (as : List α) : List α × List α
List.partition.{u} {α : Type u} (p : α Bool) (as : List α) : List α × List α

返回一对列表,它们一起包含 as 的所有元素。第一个列表包含 p 返回 true 的元素,第二个列表包含 p 返回 false 的元素。

O(|l|)as.partition p 等效于 (as.filter p, as.filter (not p)),但它的效率稍高一些,因为它只需对列表执行一次传递。

示例:

  • [1, 2, 5, 2, 7, 7].partition (· > 2) = ([5, 7, 7], [1, 2, 2])

  • [1, 2, 5, 2, 7, 7].partition (fun _ => false) = ([], [1, 2, 5, 2, 7, 7])

  • [1, 2, 5, 2, 7, 7].partition (fun _ => true) = ([1, 2, 5, 2, 7, 7], [])

🔗定义
List.partitionM.{u_1} {m : Type Type u_1} {α : Type} [Monad m] (p : α m Bool) (l : List α) : m (List α × List α)
List.partitionM.{u_1} {m : Type Type u_1} {α : Type} [Monad m] (p : α m Bool) (l : List α) : m (List α × List α)

返回一对列表,它们一起包含 as 的所有元素。第一个列表包含单子谓词 p 返回 true 的元素,第二个列表包含 p 返回 false 的元素。按从左到右的顺序检查列表的元素。

这是 List.partition 的一元版本。

例子:

def posOrNeg (x : Int) : Except String Bool := if x > 0 then pure true else if x < 0 then pure false else throw "Zero is not positive or negative"
#eval [-1, 2, 3].partitionM posOrNeg
Except.ok ([2, 3], [-1])
#eval [0, 2, 3].partitionM posOrNeg
Except.error "Zero is not positive or negative"
🔗定义
List.partitionMap.{u_1, u_2, u_3} {α : Type u_1} {β : Type u_2} {γ : Type u_3} (f : α β γ) (l : List α) : List β × List γ
List.partitionMap.{u_1, u_2, u_3} {α : Type u_1} {β : Type u_2} {γ : Type u_3} (f : α β γ) (l : List α) : List β × List γ

应用一个函数,该函数向列表的每个元素返回不相交并集,将 Sum.inlSum.inr 结果收集到单独的列表中。

示例:

🔗定义
List.groupByKey.{u, v} {α : Type u} {β : Type v} [BEq α] [Hashable α] (key : β α) (xs : List β) : Std.HashMap α (List β)
List.groupByKey.{u, v} {α : Type u} {β : Type v} [BEq α] [Hashable α] (key : β α) (xs : List β) : Std.HashMap α (List β)

根据列表 xs 的元素经函数 key 得到的结果进行分组,返回将每组与其键关联的哈希映射。各组保留元素在 xs 中的相对顺序。

示例:

Std.HashMap.ofList [(0, [0, 2, 4, 6]), (1, [1, 3, 5])]#eval [0, 1, 2, 3, 4, 5, 6].groupByKey (· % 2) Std.HashMap.ofList [(0, [0, 2, 4, 6]), (1, [1, 3, 5])]

20.15.3.13. 元素判定🔗

🔗定义
List.contains.{u} {α : Type u} [BEq α] (as : List α) (a : α) : Bool
List.contains.{u} {α : Type u} [BEq α] (as : List α) (a : α) : Bool

使用 a 比较元素,检查 as 是否属于 ==

它与所列操作对应或等价。(相关项:O(|as|)List.elem。)

此段说明该操作的行为、边界条件及推荐用法。(相关项:l.contains aLawfulBEq αl.contains a = true a ll.contains a = false a l。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:[1, 4, 2, 3, 3, 7].contains 3 = true。)

  • 示例见所列代码。(相关项:List.contains [1, 4, 2, 3, 3, 7] 5 = false。)

🔗定义
List.elem.{u} {α : Type u} [BEq α] (a : α) (l : List α) : Bool
List.elem.{u} {α : Type u} [BEq α] (a : α) (l : List α) : Bool

使用 a 比较元素,检查 l 是否属于 ==

它与所列操作对应或等价。(相关项:O(|l|)List.contains。)

此段说明该操作的行为、边界条件及推荐用法。(相关项:l.contains aLawfulBEq αl.contains a = true a ll.contains a = false a l。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:List.elem 3 [1, 4, 2, 3, 3, 7] = true。)

  • 示例见所列代码。(相关项:List.elem 5 [1, 4, 2, 3, 3, 7] = false。)

🔗定义
List.all.{u} {α : Type u} : List α (α Bool) Bool
List.all.{u} {α : Type u} : List α (α Bool) Bool

truep 的每个元素都返回 true,则返回 l

遇到第一个决定结果的值时即短路,并按所述顺序检查元素。(相关项:O(|l|)false。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:[a, b, c].all p = (p a && (p b && p c))。)

  • 示例见所列代码。(相关项:[2, 4, 6].all (· % 2 = 0) = true。)

  • 示例见所列代码。(相关项:[2, 4, 5, 6].all (· % 2 = 0) = false。)

🔗定义
List.allM.{u, v} {m : Type Type u} [Monad m] {α : Type v} (p : α m Bool) (l : List α) : m Bool
List.allM.{u, v} {m : Type Type u} [Monad m] {α : Type v} (p : α m Bool) (l : List α) : m Bool

若单子谓词 ptrue 的每个元素都返回 l,则返回 O(|l|)

遇到第一个决定结果的值时即短路,并按所述顺序检查元素。(相关项:falsel、。)

🔗定义
List.any.{u} {α : Type u} (l : List α) (p : α Bool) : Bool
List.any.{u} {α : Type u} (l : List α) (p : α Bool) : Bool

truep 的任一元素返回 true,则返回 l

遇到第一个决定结果的值时即短路,并按所述顺序检查元素。(相关项:O(|l|)true。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:[2, 4, 6].any (· % 2 = 0) = true。)

  • 示例见所列代码。(相关项:[2, 4, 6].any (· % 2 = 1) = false。)

  • 示例见所列代码。(相关项:[2, 4, 5, 6].any (· % 2 = 0) = true。)

  • 示例见所列代码。(相关项:[2, 4, 5, 6].any (· % 2 = 1) = true。)

🔗定义
List.anyM.{u, v} {m : Type Type u} [Monad m] {α : Type v} (p : α m Bool) (l : List α) : m Bool
List.anyM.{u, v} {m : Type Type u} [Monad m] {α : Type v} (p : α m Bool) (l : List α) : m Bool

若单子谓词 ptrue 的任一元素返回 l,则返回 O(|l|)

遇到第一个决定结果的值时即短路,并按所述顺序检查元素。(相关项:truel、。)

🔗定义

true 中每个元素都是 bs,则返回 true

遇到第一个决定结果的值时即短路,并按所述顺序检查元素。(相关项:O(|bs|)false。)

🔗定义

若列表 true 中存在值 true,则返回 bs

遇到第一个决定结果的值时即短路,并按所述顺序检查元素。(相关项:O(|bs|)true。)

20.15.3.14. 比较🔗

🔗定义
List.beq.{u} {α : Type u} [BEq α] : List α List α Bool
List.beq.{u} {α : Type u} [BEq α] : List α List α Bool

检查两个列表是否长度相同,且对应元素两两满足 BEq。通常通过 == 运算符使用。

🔗定义
List.isEqv.{u} {α : Type u} (as bs : List α) (eqv : α α Bool) : Bool
List.isEqv.{u} {α : Type u} (as bs : List α) (eqv : α α Bool) : Bool

返回 true,如果 asbs 长度相同,且对应元素两两满足关系 eqv

复杂度为 O(min |as| |bs|)。遇到第一对不满足关系的元素时短路。

示例:

🔗定义
List.isPerm.{u} {α : Type u} [BEq α] : List α List α Bool
List.isPerm.{u} {α : Type u} [BEq α] : List α List α Bool

返回 true,如果 l₁l₂ 互为排列。复杂度为 O(|l₁| * |l₂|)

关系 List.Perm 是排列的逻辑刻画。当 BEq α 实例与 DecidableEq α 对应时,isPerm l₁ l₂ l₁ ~ l₂(使用定理 isPerm_iff)。

🔗定义
List.isPrefixOf.{u} {α : Type u} [BEq α] : List α List α Bool
List.isPrefixOf.{u} {α : Type u} [BEq α] : List α List α Bool

检查第一个列表是否为第二个列表的前缀。

关系 List.IsPrefixOf 使用逻辑相等来表达此性质。

示例:

🔗定义
List.isPrefixOf?.{u} {α : Type u} [BEq α] (l₁ l₂ : List α) : Option (List α)
List.isPrefixOf?.{u} {α : Type u} [BEq α] (l₁ l₂ : List α) : Option (List α)

如果第一个列表是第二个列表的前缀,则返回从第二个列表中去掉该前缀后的结果。

换言之,isPrefixOf? l₁ l₂ 返回 some t,当且仅当 l₂ == l₁ ++ t

示例:

🔗定义
List.isSublist.{u} {α : Type u} [BEq α] : List α List α Bool
List.isSublist.{u} {α : Type u} [BEq α] : List α List α Bool

如果第一个列表是第二个列表的子序列(不要求连续),则为真;元素使用 == 运算符比较。

关系 List.Sublist 是此性质的逻辑刻画。

示例:

🔗定义
List.isSuffixOf.{u} {α : Type u} [BEq α] (l₁ l₂ : List α) : Bool
List.isSuffixOf.{u} {α : Type u} [BEq α] (l₁ l₂ : List α) : Bool

检查第一个列表是否为第二个列表的后缀。

关系 List.IsSuffixOf 使用逻辑相等来表达此性质。

示例:

🔗定义
List.isSuffixOf?.{u} {α : Type u} [BEq α] (l₁ l₂ : List α) : Option (List α)
List.isSuffixOf?.{u} {α : Type u} [BEq α] (l₁ l₂ : List α) : Option (List α)

如果第一个列表是第二个列表的后缀,则返回从第二个列表中去掉该后缀后的结果。

换言之,isSuffixOf? l₁ l₂ 返回 some t,当且仅当 l₂ == t ++ l₁

示例:

🔗定义
List.le.{u} {α : Type u} [LT α] (as bs : List α) : Prop
List.le.{u} {α : Type u} [LT α] (as bs : List α) : Prop

列表相对于其元素严格顺序的非严格顺序。

as bs 成立,如果 ¬ bs < as

如果底层 LT α 实例具有良好性质,则可将此关系视为字典序。具体而言,它应满足非自反性、非对称性和反对称性。这些要求在 List.cons_le_cons_iff 中有精确表述。若这些性质成立,则 as bs 当且仅当:

  • as 为空;或

  • asbs 都非空,且 as 的首元素小于 bs 的首元素;或

  • asbs 都非空、首元素相等,且 as 的尾部小于或等于 bs 的尾部。

🔗定义
List.lt.{u} {α : Type u} [LT α] : List α List α Prop
List.lt.{u} {α : Type u} [LT α] : List α List α Prop

列表相对于其元素顺序的字典序。

当满足以下条件之一时,as < bs

  • as 为空且 bs 非空;或

  • asbs 都非空,且 as 的首元素小于 bs 的首元素;或

  • asbs 都非空、首元素相等,且 as 的尾部小于 bs 的尾部。

🔗定义
List.lex.{u} {α : Type u} [BEq α] (l₁ l₂ : List α) (lt : α α Bool := by exact < ·)) : Bool
List.lex.{u} {α : Type u} [BEq α] (l₁ l₂ : List α) (lt : α α Bool := by exact < ·)) : Bool

根据元素上的比较按字典序比较列表。

相对于 lt 的字典序定义如下:

  • [].lex (b :: bs)true

  • as.lex [] = falsefalse

  • (a :: as).lex (b :: bs) 为真,如果 lt a b,或者 a == blex lt as bs 为真。

20.15.3.15. 终止辅助🔗

🔗定义
List.attach.{u_1} {α : Type u_1} (l : List α) : List { x // x l }
List.attach.{u_1} {α : Type u_1} (l : List α) : List { x // x l }

l 的每个元素“附加”它确实属于 l 的证明,得到元素相同但位于子类型 { x // x l } 中的新列表。

O(1).

此函数主要用于良基递归的终止性证明,使迭代操作取得的值能与原参数建立所需关系。(相关项:相关说明List.map。)

🔗定义
List.attachWith.{u_1} {α : Type u_1} (l : List α) (P : α Prop) (H : (x : α), x l P x) : List { x // P x }
List.attachWith.{u_1} {α : Type u_1} (l : List α) (P : α Prop) (H : (x : α), x l P x) : List { x // P x }

为满足谓词 P 的值列表逐一“附加”证明,返回相应子类型 { x // P x } 中的元素列表。

O(1).

🔗定义
List.unattach.{u_1} {α : Type u_1} {p : α Prop} (l : List { x // p x }) : List α
List.unattach.{u_1} {α : Type u_1} {p : α Prop} (l : List { x // p x }) : List α

忘掉子类型元素满足谓词的证明,把子类型中的项列表映射回原类型中的相应项。

它与所列操作对应或等价。(相关项:List.attachWithl.map (·.val)。)

此段说明该操作的行为、边界条件及推荐用法。(相关项:map_subtypeunattach_attach。)

此函数主要用于良基递归的终止性证明,使迭代操作取得的值能与原参数建立所需关系。(相关项:相关说明simp [List.unattach, -List.map_subtype]。)

🔗定义
List.pmap.{u_1, u_2} {α : Type u_1} {β : Type u_2} {P : α Prop} (f : (a : α) P a β) (l : List α) (H : (a : α), a l P a) : List β
List.pmap.{u_1, u_2} {α : Type u_1} {β : Type u_2} {P : α Prop} (f : (a : α) P a β) (l : List α) (H : (a : α), a l P a) : List β

给定 α 的每个元素都满足 P 的证明,把只在满足 l : List αl 项上定义的部分函数映射到 P 上。

此段说明该操作的行为、边界条件及推荐用法。(相关项:O(|l|)List.pmapList.map。)