Lean 语言参考

13.5. 数字文字🔗

有两种数字文字:自然数文字和 科学文字。 两者均通过 类型类 重载。

13.5.1. 自然数🔗

自然数可以多种形式指定:

  • 0 到 9 的数字序列是十进制文字

  • 0b0B 后跟一个或多个 0 和 1 的序列是二进制文字

  • 0o0O 后跟一个或多个数字 0 到 7 的序列是八进制文字

  • 0x0X 后跟一系列一个或多个十六进制数字(0 到 9 以及 A 到 F,不区分大小写)是十六进制文字

所有数字文字也可以包含内部下划线,二进制、八进制或十六进制文字中的前两个字符之间除外。 这些旨在以自然的方式帮助数字组,例如 1_000_0000x_c0de_cafe。 (虽然可以将数字 123 写为 1_2__3,但不建议这样做。)

当 Lean 遇到自然数文字 n 时,它通过重载方法 OfNat.ofNat n 对其进行解释。 OfNat Nat n默认实例 确保在不存在其他类型信息时可以推断类型 Nat

🔗type class
OfNat.{u} (α : Type u) : Nat Type u
OfNat.{u} (α : Type u) : Nat Type u

The class OfNat α n powers the numeric literal parser. If you write 37 : α, Lean will attempt to synthesize OfNat α 37, and will generate the term (OfNat.ofNat 37 : α).

There is a bit of infinite regress here since the desugaring apparently still contains a literal 37 in it. The type of expressions contains a primitive constructor for "raw natural number literals", which you can directly access using the macro nat_lit 37. Raw number literals are always of type Nat. So it would be more correct to say that Lean looks for an instance of OfNat α (nat_lit 37), and it generates the term (OfNat.ofNat (nat_lit 37) : α).

Instance Constructor

OfNat.mk.{u}

Methods

ofNat : α

The OfNat.ofNat function is automatically inserted by the parser when the user writes a numeric literal like 1 : α. Implementations of this typeclass can therefore customize the behavior of n : α based on n and α.

Custom Natural Number Literals

结构体NatInterval表示自然数的区间。

structure NatInterval where low : Nat high : Nat low_le_high : low high instance : Add NatInterval where add | lo1, hi1, le1, lo2, hi2, le2 => lo1 + lo2, hi1 + hi2, lo1:Nathi1:Natle1:lo1 hi1lo2:Nathi2:Natle2:lo2 hi2lo1 + lo2 hi1 + hi2 All goals completed! 🐙

OfNat 实例允许使用自然数文字来表示间隔:

instance : OfNat NatInterval n where ofNat := n, n, n:Natn n All goals completed! 🐙 { low := 8, high := 8, low_le_high := _ }#eval (8 : NatInterval)
{ low := 8, high := 8, low_le_high := _ }
{ low := 7, high := 7, low_le_high := _ }#eval (0b111 : NatInterval)
{ low := 7, high := 7, low_le_high := _ }

没有单独的整数文字。 诸如 -5 之类的术语由应用于自然数文字的前缀否定(可以通过 Neg 类型类重载)组成。

13.5.2. 科学数字🔗

科学数字文字由一系列十进制数字组成,后跟(不插入空格)可选的小数部分(句号后跟零个或多个十进制数字)和可选的指数部分(字母 e 后跟可选的 +-,然后后跟一个或多个十进制数字)。 科学数字通过 OfScientific 类型类重载。

🔗type class
OfScientific.{u} (α : Type u) : Type u
OfScientific.{u} (α : Type u) : Type u

For decimal and scientific numbers (e.g., 1.23, 3.12e10). Examples:

Note the use of nat_lit; there is no wrapping OfNat.ofNat in the resulting term.

Instance Constructor

OfScientific.mk.{u}

Methods

ofScientific : Nat  Bool  Nat  α

Produces a value from the given mantissa, exponent sign, and decimal exponent. For the exponent sign, true indicates a negative exponent.

Examples:

Note the use of nat_lit; there is no wrapping OfNat.ofNat in the resulting term.

FloatFloat32 有一个 OfScientific 实例,但没有单独的浮点文字。

13.5.3. 弦乐🔗

字符串文字在 字符串章节中进行了描述。

13.5.4. 列表和数组🔗

列表和数组文字包含括号内以逗号分隔的元素序列,数组以哈希标记 (#) 为前缀。 数组文字被解释为包含在转换调用中的列表文字。 出于性能原因,非常大的列表和数组文字会转换为局部定义序列,而不仅仅是列表构造函数的迭代应用程序。

syntaxList Literals
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,*]
syntaxArray Literals
term ::= ...
    | Syntax for `Array α`. 

Conventions for notations in identifiers:

 * The recommended spelling of `#[]` in identifiers is `empty`.

 * The recommended spelling of `#[x]` in identifiers is `singleton`.#[term,*]
Long List Literals

该列表包含 32 个元素。 生成的代码是List.cons的迭代应用:

[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] : List Nat#check [1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] : List Nat

具有 33 个元素的列表文字成为局部定义的序列:

let y := let y := let y := [1, 1, 1, 1, 1]; 1 :: 1 :: 1 :: 1 :: y; let y := 1 :: 1 :: 1 :: 1 :: y; 1 :: 1 :: 1 :: 1 :: y; let y := let y := 1 :: 1 :: 1 :: 1 :: y; 1 :: 1 :: 1 :: 1 :: y; let y := 1 :: 1 :: 1 :: 1 :: y; 1 :: 1 :: 1 :: 1 :: y : List Nat#check [1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1]
let y :=
  let y :=
    let y := [1, 1, 1, 1, 1];
    1 :: 1 :: 1 :: 1 :: y;
  let y := 1 :: 1 :: 1 :: 1 :: y;
  1 :: 1 :: 1 :: 1 :: y;
let y :=
  let y := 1 :: 1 :: 1 :: 1 :: y;
  1 :: 1 :: 1 :: 1 :: y;
let y := 1 :: 1 :: 1 :: 1 :: y;
1 :: 1 :: 1 :: 1 :: y : List Nat