The Lean Language Reference

19.8.Β StringsπŸ”—

Strings represent Unicode text. Strings are specially supported by Lean:

  • They have a logical model that specifies their behavior in terms of ByteArrays that contain UTF-8 scalar values.

  • In compiled code, they have a run-time representation that additionally includes a cached length, measured as the number of scalar values. Additionally, the Lean runtime contains optimized implementations of string operations.

  • There is string literal syntax for writing strings.

UTF-8 is a variable-width encoding. A character may be encoded as a one, two, three, or four byte code unit. The fact that strings are UTF-8-encoded byte arrays is visible in the API:

  • There is no operation to project a particular character out of the string, as this would be a performance trap. Use a String.Iterator in a loop instead of a Nat.

  • Strings are indexed by String.ValidPos, which internally records byte counts rather than character counts, and thus takes constant time. String.ValidPos includes a proof that the byte count in fact points at the beginning of a UTF-8 code unit. Aside from 0, these should not be constructed directly, but rather updated using String.next and String.prev.

19.8.1.Β Logical Model

πŸ”—structure
String : Type
String : Type

A string is a sequence of Unicode scalar values.

At runtime, strings are represented by dynamic arrays of bytes using the UTF-8 encoding. Both the size in bytes (String.utf8ByteSize) and in characters (String.length) are cached and take constant time. Many operations on strings perform in-place modifications when the reference to the string is unique.

Constructor

String.ofByteArray

Fields

bytes : ByteArray

The bytes of the UTF-8 encoding of the string. Since strings have a special representation in the runtime, this function actually takes linear time and space at runtime. For efficient access to the string's bytes, use String.utf8ByteSize and String.getUTF8Byte.

isValidUTF8 : self.bytes.IsValidUTF8

The bytes of the string form valid UTF-8.

The logical model of strings in Lean is a structure that contains a single field, which is a list of characters. This is convenient when specifying and proving properties of string-processing functions at a low level.

19.8.2.Β Run-Time RepresentationπŸ”—

Memory layout of strings

Memory layout of strings

Strings are represented as dynamic arrays of bytes, encoded in UTF-8. After the object header, a string contains:

byte count

The number of bytes that currently contain valid string data

capacity

The number of bytes presently allocated for the string

length

The length of the encoded string, which may be shorter than the byte count due to UTF-8 multi-byte characters

data

The actual character data in the string, null-terminated

Many string functions in the Lean runtime check whether they have exclusive access to their argument by consulting the reference count in the object header. If they do, and the string's capacity is sufficient, then the existing string can be mutated rather than allocating fresh memory. Otherwise, a new string must be allocated.

19.8.2.1.Β Performance NotesπŸ”—

Despite the fact that they appear to be an ordinary constructor and projection, String.mk and String.data take time linear in the length of the string. This is because they must implement the conversions between lists of characters and packed arrays of bytes, which must necessarily visit each character.

19.8.3.Β SyntaxπŸ”—

Lean has three kinds of string literals: ordinary string literals, interpolated string literals, and raw string literals.

19.8.3.1.Β String LiteralsπŸ”—

String literals begin and end with a double-quote character ". Between these characters, they may contain any other character, including newlines, which are included literally (with the caveat that all newlines in a Lean source file are interpreted as '\n', regardless of file encoding and platform). Special characters that cannot otherwise be written in string literals may be escaped with a backslash, so "\"Quotes\"" is a string literal that begins and ends with double quotes. The following forms of escape sequences are accepted:

\r, \n, \t, \\, \", \'

These escape sequences have the usual meaning, mapping to CR, LF, tab, backslash, double quote, and single quote, respectively.

\xNN

When NN is a sequence of two hexadecimal digits, this escape denotes the character whose Unicode code point is indicated by the two-digit hexadecimal code.

\uNNNN

When NN is a sequence of two hexadecimal digits, this escape denotes the character whose Unicode code point is indicated by the four-digit hexadecimal code.

String literals may contain gaps. A gap is indicated by an escaped newline, with no intervening characters between the escaping backslash and the newline. In this case, the string denoted by the literal is missing the newline and all leading whitespace from the next line. String gaps may not precede lines that contain only whitespace.

Here, str1 and str2 are the same string:

def str1 := "String with \ a gap" def str2 := "String with a gap" example : str1 = str2 := rfl

If the line following the gap is empty, the string is rejected:

def str3 := "String with \unexpected additional newline in string gap 
             a gap"

The parser error is:

<example>:2:0-3:0: unexpected additional newline in string gap

19.8.3.2.Β Interpolated StringsπŸ”—

Preceding a string literal with s! causes it to be processed as an interpolated string, in which regions of the string surrounded by { and } characters are parsed and interpreted as Lean expressions. Interpolated strings are interpreted by appending the string that precedes the interpolation, the expression (with an added call to toString surrounding it), and the string that follows the interpolation.

For example:

example : s!"1 + 1 = {1 + 1}\n" = "1 + 1 = " ++ toString (1 + 1) ++ "\n" := rfl

Preceding a literal with m! causes the interpolation to result in an instance of MessageData, the compiler's internal data structure for messages to be shown to users.

19.8.3.3.Β Raw String LiteralsπŸ”—

In raw string literals, there are no escape sequences or gaps, and each character denotes itself exactly. Raw string literals are preceded by r, followed by zero or more hash characters (#) and a double quote ". The string literal is completed at a double quote that is followed by the same number of hash characters. For example, they can be used to avoid the need to double-escape certain characters:

example : r"\t" = "\\t" := rfl "Write backslash in a string using '\\\\\\\\'"#eval r"Write backslash in a string using '\\\\'"

The #eval yields:

"Write backslash in a string using '\\\\\\\\'"

Including hash marks allows the strings to contain unescaped quotes:

example : r#"This is "literally" quoted"# = "This is \"literally\" quoted" := rfl

Adding sufficiently many hash marks allows any raw literal to be written literally:

example : r##"This is r#"literally"# quoted"## = "This is r#\"literally\"# quoted" := rfl

19.8.4.Β API ReferenceπŸ”—

19.8.4.1.Β ConstructingπŸ”—

πŸ”—def
String.singleton (c : Char) : String
String.singleton (c : Char) : String

Returns a new string that contains only the character c.

Because strings are encoded in UTF-8, the resulting string may take multiple bytes.

Examples:

πŸ”—def
String.append (s : String) (t : String) : String
String.append (s : String) (t : String) : String

Appends two strings. Usually accessed via the ++ operator.

The internal implementation will perform destructive updates if the string is not shared.

Examples:

  • "abc".append "def" = "abcdef"

  • "abc" ++ "def" = "abcdef"

  • "" ++ "" = ""

πŸ”—def
String.join (l : List String) : String
String.join (l : List String) : String

Appends all the strings in a list of strings, in order.

Use String.intercalate to place a separator string between the strings in a list.

Examples:

πŸ”—def
String.intercalate (s : String) : List String β†’ String
String.intercalate (s : String) : List String β†’ String

Appends the strings in a list of strings, placing the separator s between each pair.

Examples:

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

  • " and ".intercalate ["tea", "coffee"] = "tea and coffee"

  • " | ".intercalate ["M", "", "N"] = "M | | N"

19.8.4.2.Β ConversionsπŸ”—

πŸ”—def
String.toList (s : String) : List Char
String.toList (s : String) : List Char

Converts a string to a list of characters.

Since strings are represented as dynamic arrays of bytes containing the string encoded using UTF-8, this operation takes time and space linear in the length of the string.

Examples:

πŸ”—def
String.isNat (s : String) : Bool
String.isNat (s : String) : Bool

Checks whether the string can be interpreted as the decimal representation of a natural number.

A string can be interpreted as a decimal natural number if it is not empty and all the characters in it are digits.

Use String.toNat? or String.toNat! to convert such a string to a natural number.

Examples:

πŸ”—def
String.toNat? (s : String) : Option Nat
String.toNat? (s : String) : Option Nat

Interprets a string as the decimal representation of a natural number, returning it. Returns none if the string does not contain a decimal natural number.

A string can be interpreted as a decimal natural number if it is not empty and all the characters in it are digits.

Use String.isNat to check whether String.toNat? would return some. String.toNat! is an alternative that panics instead of returning none when the string is not a natural number.

Examples:

πŸ”—def
String.toNat! (s : String) : Nat
String.toNat! (s : String) : Nat

Interprets a string as the decimal representation of a natural number, returning it. Panics if the string does not contain a decimal natural number.

A string can be interpreted as a decimal natural number if it is not empty and all the characters in it are digits.

Use String.isNat to check whether String.toNat! would return a value. String.toNat? is a safer alternative that returns none instead of panicking when the string is not a natural number.

Examples:

πŸ”—def
String.isInt (s : String) : Bool
String.isInt (s : String) : Bool

Checks whether the string can be interpreted as the decimal representation of an integer.

A string can be interpreted as a decimal integer if it only consists of at least one decimal digit and optionally - in front. Leading + characters are not allowed.

Use String.toInt? or String.toInt! to convert such a string to an integer.

Examples:

πŸ”—def
String.toInt? (s : String) : Option Int
String.toInt? (s : String) : Option Int

Interprets a string as the decimal representation of an integer, returning it. Returns none if the string does not contain a decimal integer.

A string can be interpreted as a decimal integer if it only consists of at least one decimal digit and optionally - in front. Leading + characters are not allowed.

Use String.isInt to check whether String.toInt? would return some. String.toInt! is an alternative that panics instead of returning none when the string is not an integer.

Examples:

πŸ”—def
String.toInt! (s : String) : Int
String.toInt! (s : String) : Int

Interprets a string as the decimal representation of an integer, returning it. Panics if the string does not contain a decimal integer.

A string can be interpreted as a decimal integer if it only consists of at least one decimal digit and optionally - in front. Leading + characters are not allowed.

Use String.isInt to check whether String.toInt! would return a value. String.toInt? is a safer alternative that returns none instead of panicking when the string is not an integer.

Examples:

πŸ”—def
String.toFormat (s : String) : Std.Format
String.toFormat (s : String) : Std.Format

Converts a string to a pretty-printer document, replacing newlines in the string with Std.Format.line.

19.8.4.3.Β PropertiesπŸ”—

πŸ”—def
String.isEmpty (s : String) : Bool
String.isEmpty (s : String) : Bool

Checks whether a string is empty.

Empty strings are equal to "" and have length and end position 0.

Examples:

πŸ”—def
String.length (b : String) : Nat
String.length (b : String) : Nat

Returns the length of a string in Unicode code points.

Examples:

19.8.4.4.Β PositionsπŸ”—

πŸ”—structure
String.ValidPos (s : String) : Type
String.ValidPos (s : String) : Type

A ValidPos s is a byte offset in s together with a proof that this position is at a UTF-8 character boundary.

Constructor

String.ValidPos.mk

Fields

offset : String.Pos.Raw

The underlying byte offset of the ValidPos.

isValid : String.Pos.Raw.IsValid s self.offset

The proof that offset is valid for the string s.

πŸ”—def
String.ValidPos.get {s : String} (pos : s.ValidPos) (h : pos β‰  s.endValidPos) : Char
String.ValidPos.get {s : String} (pos : s.ValidPos) (h : pos β‰  s.endValidPos) : Char

Returns the character at the position pos of a string, taking a proof that p is not the past-the-end position.

This function is overridden with an efficient implementation in runtime code.

Examples:

πŸ”—def
String.ValidPos.get! {s : String} (pos : s.ValidPos) : Char
String.ValidPos.get! {s : String} (pos : s.ValidPos) : Char

Returns the character at the position pos of a string, or panics if the position is the past-the-end position.

This function is overridden with an efficient implementation in runtime code.

πŸ”—def
String.ValidPos.get? {s : String} (pos : s.ValidPos) : Option Char
String.ValidPos.get? {s : String} (pos : s.ValidPos) : Option Char

Returns the character at the position pos of a string, or none if the position is the past-the-end position.

This function is overridden with an efficient implementation in runtime code.

πŸ”—def
String.ValidPos.byte {s : String} (pos : s.ValidPos) (h : pos β‰  s.endValidPos) : UInt8
String.ValidPos.byte {s : String} (pos : s.ValidPos) (h : pos β‰  s.endValidPos) : UInt8

Returns the byte at the position pos of a string.

πŸ”—def
String.ValidPos.prev {s : String} (pos : s.ValidPos) (h : pos β‰  s.startValidPos) : s.ValidPos
String.ValidPos.prev {s : String} (pos : s.ValidPos) (h : pos β‰  s.startValidPos) : s.ValidPos

Returns the previous valid position before the given position, given a proof that the position is not the start position, which guarantees that such a position exists.

πŸ”—def
String.ValidPos.prev! {s : String} (pos : s.ValidPos) : s.ValidPos
String.ValidPos.prev! {s : String} (pos : s.ValidPos) : s.ValidPos

Returns the previous valid position before the given position, or panics if the position is the start position.

πŸ”—def
String.ValidPos.prev? {s : String} (pos : s.ValidPos) : Option s.ValidPos
String.ValidPos.prev? {s : String} (pos : s.ValidPos) : Option s.ValidPos

Returns the previous valid position before the given position, or none if the position is the start position.

πŸ”—def
String.ValidPos.next {s : String} (pos : s.ValidPos) (h : pos β‰  s.endValidPos) : s.ValidPos
String.ValidPos.next {s : String} (pos : s.ValidPos) (h : pos β‰  s.endValidPos) : s.ValidPos

Advances a valid position on a string to the next valid position, given a proof that the position is not the past-the-end position, which guarantees that such a position exists.

πŸ”—def
String.ValidPos.next! {s : String} (pos : s.ValidPos) : s.ValidPos
String.ValidPos.next! {s : String} (pos : s.ValidPos) : s.ValidPos

Advances a valid position on a string to the next valid position, or panics if the given position is the past-the-end position.

πŸ”—def
String.ValidPos.next? {s : String} (pos : s.ValidPos) : Option s.ValidPos
String.ValidPos.next? {s : String} (pos : s.ValidPos) : Option s.ValidPos

Advances a valid position on a string to the next valid position, or returns none if the given position is the past-the-end position.

πŸ”—def
String.ValidPos.cast {s t : String} (pos : s.ValidPos) (h : s = t) : t.ValidPos
String.ValidPos.cast {s t : String} (pos : s.ValidPos) (h : s = t) : t.ValidPos

Constructs a valid position on t from a valid position on s and a proof that s = t.

πŸ”—def
String.ValidPos.ofCopy {s : String.Slice} (pos : s.copy.ValidPos) : s.Pos
String.ValidPos.ofCopy {s : String.Slice} (pos : s.copy.ValidPos) : s.Pos

Given a slice s and a position on s.copy, obtain the corresponding position on s.

πŸ”—def
String.ValidPos.extract {s : String} (b e : s.ValidPos) : String
String.ValidPos.extract {s : String} (b e : s.ValidPos) : String
πŸ”—def
String.ValidPos.toSlice {s : String} (pos : s.ValidPos) : s.toSlice.Pos
String.ValidPos.toSlice {s : String} (pos : s.ValidPos) : s.toSlice.Pos

Turns a valid position on the string s into a valid position on the slice s.toSlice.

19.8.4.5.Β Raw PositionsπŸ”—

πŸ”—structure
String.Pos.Raw : Type
String.Pos.Raw : Type

A byte position in a String, according to its UTF-8 encoding.

Character positions (counting the Unicode code points rather than bytes) are represented by plain Nats. Indexing a String by a String.Pos.Raw takes constant time, while character positions need to be translated internally to byte positions, which takes linear time.

A byte position p is valid for a string s if 0 ≀ p ≀ s.endPos and p lies on a UTF-8 character boundary, see String.Pos.IsValid.

There is another type, String.ValidPos, which bundles the validity predicate. Using String.ValidPos instead of String.Pos.Raw is recommended because it will lead to less error handling and fewer edge cases.

Constructor

String.Pos.Raw.mk

Fields

byteIdx : Nat

Get the underlying byte index of a String.Pos.Raw

πŸ”—def
String.Pos.Raw.isValid (s : String) (p : String.Pos.Raw) : Bool
String.Pos.Raw.isValid (s : String) (p : String.Pos.Raw) : Bool

Returns true if p is a valid UTF-8 position in the string s.

This means that p ≀ s.endPos and p lies on a UTF-8 character boundary. At runtime, this operation takes constant time.

Examples:

  • String.Pos.isValid "abc" ⟨0⟩ = true

  • String.Pos.isValid "abc" ⟨1⟩ = true

  • String.Pos.isValid "abc" ⟨3⟩ = true

  • String.Pos.isValid "abc" ⟨4⟩ = false

  • String.Pos.isValid "𝒫(A)" ⟨0⟩ = true

  • String.Pos.isValid "𝒫(A)" ⟨1⟩ = false

  • String.Pos.isValid "𝒫(A)" ⟨2⟩ = false

  • String.Pos.isValid "𝒫(A)" ⟨3⟩ = false

  • String.Pos.isValid "𝒫(A)" ⟨4⟩ = true

πŸ”—def
String.Pos.Raw.isValidForSlice (s : String.Slice) (p : String.Pos.Raw) : Bool
String.Pos.Raw.isValidForSlice (s : String.Slice) (p : String.Pos.Raw) : Bool

Efficiently checks whether a position is at a UTF-8 character boundary of the slice s.

πŸ”—def
String.atEnd : String β†’ String.Pos.Raw β†’ Bool
String.atEnd : String β†’ String.Pos.Raw β†’ Bool

Returns true if a specified byte position is greater than or equal to the position which points to the end of a string. Otherwise, returns false.

Examples:

πŸ”—def
String.endPos (s : String) : String.Pos.Raw
String.endPos (s : String) : String.Pos.Raw

A UTF-8 byte position that points at the end of a string, just after the last character.

  • "abc".endPos = ⟨3⟩

  • "Lβˆƒβˆ€N".endPos = ⟨8⟩

πŸ”—def
String.next (s : String) (p : String.Pos.Raw) : String.Pos.Raw
String.next (s : String) (p : String.Pos.Raw) : String.Pos.Raw

Returns the next position in a string after position p. If p is not a valid position or p = s.endPos, returns the position one byte after p.

A run-time bounds check is performed to determine whether p is at the end of the string. If a bounds check has already been performed, use String.next' to avoid a repeated check.

Some examples of edge cases:

  • "abc".next ⟨3⟩ = ⟨4⟩, since 3 = "abc".endPos

  • "Lβˆƒβˆ€N".next ⟨2⟩ = ⟨3⟩, since 2 points into the middle of a multi-byte UTF-8 character

Examples:

  • "abc".get ("abc".next 0) = 'b'

  • "Lβˆƒβˆ€N".get (0 |> "Lβˆƒβˆ€N".next |> "Lβˆƒβˆ€N".next) = 'βˆ€'

πŸ”—def
String.next' (s : String) (p : String.Pos.Raw) (h : Β¬s.atEnd p = true) : String.Pos.Raw
String.next' (s : String) (p : String.Pos.Raw) (h : Β¬s.atEnd p = true) : String.Pos.Raw

Returns the next position in a string after position p. The result is unspecified if p is not a valid position.

Requires evidence, h, that p is within bounds. No run-time bounds check is performed, as in String.next.

A typical pattern combines String.next' with a dependent if-expression to avoid the overhead of an additional bounds check. For example:

def next? (s : String) (p : `String.Pos` has been deprecated: Use `String.Pos.Raw` instead Note: The updated constant is in a different namespace. Dot notation may need to be changed (e.g., from `x.Pos` to `String.Pos.Raw x`).String.Pos) : Option Char := if h : s.atEnd p then none else s.get (s.next' p h)

Example:

πŸ”—def
String.nextWhile (s : String) (p : Char β†’ Bool) (i : String.Pos.Raw) : String.Pos.Raw
String.nextWhile (s : String) (p : Char β†’ Bool) (i : String.Pos.Raw) : String.Pos.Raw

Repeatedly increments a position in a string, as if by String.next, while the predicate p returns true for the character at the position. Stops incrementing at the end of the string or when p returns false for the current character.

Examples:

πŸ”—def
String.nextUntil (s : String) (p : Char β†’ Bool) (i : String.Pos.Raw) : String.Pos.Raw
String.nextUntil (s : String) (p : Char β†’ Bool) (i : String.Pos.Raw) : String.Pos.Raw

Repeatedly increments a position in a string, as if by String.next, while the predicate p returns false for the character at the position. Stops incrementing at the end of the string or when p returns true for the current character.

Examples:

πŸ”—def
String.prev : String β†’ String.Pos.Raw β†’ String.Pos.Raw
String.prev : String β†’ String.Pos.Raw β†’ String.Pos.Raw

Returns the position in a string before a specified position, p. If p = ⟨0⟩, returns 0. If p is greater than endPos, returns the position one byte before p. Otherwise, if p occurs in the middle of a multi-byte character, returns the beginning position of that character.

For example, "Lβˆƒβˆ€N".prev ⟨3⟩ is ⟨1⟩, since byte 3 occurs in the middle of the multi-byte character 'βˆƒ' that starts at byte 1.

Examples:

  • "abc".get ("abc".endPos |> "abc".prev) = 'c'

  • "Lβˆƒβˆ€N".get ("Lβˆƒβˆ€N".endPos |> "Lβˆƒβˆ€N".prev |> "Lβˆƒβˆ€N".prev |> "Lβˆƒβˆ€N".prev) = 'βˆƒ'

πŸ”—def
String.Pos.Raw.min (p₁ pβ‚‚ : String.Pos.Raw) : String.Pos.Raw
String.Pos.Raw.min (p₁ pβ‚‚ : String.Pos.Raw) : String.Pos.Raw

Returns either p₁ or pβ‚‚, whichever has the least byte index.

πŸ”—def
String.Pos.Raw.inc (p : String.Pos.Raw) : String.Pos.Raw
String.Pos.Raw.inc (p : String.Pos.Raw) : String.Pos.Raw

Increases the byte offset of the position by 1. Not to be confused with ValidPos.next.

πŸ”—def
String.Pos.Raw.dec (p : String.Pos.Raw) : String.Pos.Raw
String.Pos.Raw.dec (p : String.Pos.Raw) : String.Pos.Raw

Decreases the byte offset of the position by 1. Not to be confused with ValidPos.prev.

19.8.4.6.Β Lookups and ModificationsπŸ”—

πŸ”—def
String.get (s : String) (p : String.Pos.Raw) : Char
String.get (s : String) (p : String.Pos.Raw) : Char

Returns the character at position p of a string. If p is not a valid position, returns the fallback value (default : Char), which is 'A', but does not panic.

This function is overridden with an efficient implementation in runtime code. See String.utf8GetAux for the reference implementation.

Examples:

  • "abc".get ⟨1⟩ = 'b'

  • "abc".get ⟨3⟩ = (default : Char) because byte 3 is at the end of the string.

  • "Lβˆƒβˆ€N".get ⟨2⟩ = (default : Char) because byte 2 is in the middle of 'βˆƒ'.

πŸ”—def
String.get? : String β†’ String.Pos.Raw β†’ Option Char
String.get? : String β†’ String.Pos.Raw β†’ Option Char

Returns the character at position p of a string. If p is not a valid position, returns none.

This function is overridden with an efficient implementation in runtime code. See String.utf8GetAux? for the reference implementation.

Examples:

  • "abc".get? ⟨1⟩ = some 'b'

  • "abc".get? ⟨3⟩ = none

  • "Lβˆƒβˆ€N".get? ⟨1⟩ = some 'βˆƒ'

  • "Lβˆƒβˆ€N".get? ⟨2⟩ = none

πŸ”—def
String.get! (s : String) (p : String.Pos.Raw) : Char
String.get! (s : String) (p : String.Pos.Raw) : Char

Returns the character at position p of a string. Panics if p is not a valid position.

See String.get? for a safer alternative.

This function is overridden with an efficient implementation in runtime code. See String.utf8GetAux for the reference implementation.

Examples

  • "abc".get! ⟨1⟩ = 'b'

πŸ”—def
String.get' (s : String) (p : String.Pos.Raw) (h : Β¬s.atEnd p = true) : Char
String.get' (s : String) (p : String.Pos.Raw) (h : Β¬s.atEnd p = true) : Char

Returns the character at position p of a string. Returns (default : Char), which is 'A', if p is not a valid position.

Requires evidence, h, that p is within bounds instead of performing a run-time bounds check as in String.get.

A typical pattern combines get' with a dependent if-expression to avoid the overhead of an additional bounds check. For example:

def getInBounds? (s : String) (p : `String.Pos` has been deprecated: Use `String.Pos.Raw` instead Note: The updated constant is in a different namespace. Dot notation may need to be changed (e.g., from `x.Pos` to `String.Pos.Raw x`).String.Pos) : Option Char := if h : s.atEnd p then none else some (s.get' p h)

Even with evidence of Β¬ s.atEnd p, p may be invalid if a byte index points into the middle of a multi-byte UTF-8 character. For example, "Lβˆƒβˆ€N".get' ⟨2⟩ (by decide) = (default : Char).

Examples:

πŸ”—def
String.extract : String β†’ String.Pos.Raw β†’ String.Pos.Raw β†’ String
String.extract : String β†’ String.Pos.Raw β†’ String.Pos.Raw β†’ String

Creates a new string that consists of the region of the input string delimited by the two positions.

The result is "" if the start position is greater than or equal to the end position or if the start position is at the end of the string. If either position is invalid (that is, if either points at the middle of a multi-byte UTF-8 character) then the result is unspecified.

Examples:

  • "red green blue".extract ⟨0⟩ ⟨3⟩ = "red"

  • "red green blue".extract ⟨3⟩ ⟨0⟩ = ""

  • "red green blue".extract ⟨0⟩ ⟨100⟩ = "red green blue"

  • "red green blue".extract ⟨4⟩ ⟨100⟩ = "green blue"

  • "Lβˆƒβˆ€N".extract ⟨1⟩ ⟨2⟩ = "βˆƒβˆ€N"

  • "Lβˆƒβˆ€N".extract ⟨2⟩ ⟨100⟩ = ""

πŸ”—def
String.take (s : String) (n : Nat) : String
String.take (s : String) (n : Nat) : String

Creates a new string that contains the first n characters (Unicode code points) of s.

If n is greater than s.length, returns s.

Examples:

  • "red green blue".take 3 = "red"

  • "red green blue".take 1 = "r"

  • "red green blue".take 0 = ""

  • "red green blue".take 100 = "red green blue"

πŸ”—def
String.takeWhile (s : String) (p : Char β†’ Bool) : String
String.takeWhile (s : String) (p : Char β†’ Bool) : String

Creates a new string that contains the longest prefix of s in which p returns true for all characters.

Examples:

  • "red green blue".takeWhile (Β·.isLetter) = "red"

  • "red green blue".takeWhile (Β·== 'r') = "r"

  • "red green blue".takeWhile (Β·!= 'n') = "red gree"

  • "red green blue".takeWhile (fun _ => true) = "red green blue"

πŸ”—def
String.takeRight (s : String) (n : Nat) : String
String.takeRight (s : String) (n : Nat) : String

Creates a new string that contains the last n characters (Unicode code points) of s.

If n is greater than s.length, returns s.

Examples:

πŸ”—def
String.takeRightWhile (s : String) (p : Char β†’ Bool) : String
String.takeRightWhile (s : String) (p : Char β†’ Bool) : String

Creates a new string that contains the longest suffix of s in which p returns true for all characters.

Examples:

πŸ”—def
String.drop (s : String) (n : Nat) : String
String.drop (s : String) (n : Nat) : String

Removes the specified number of characters (Unicode code points) from the start of the string.

If n is greater than s.length, returns "".

Examples:

  • "red green blue".drop 4 = "green blue"

  • "red green blue".drop 10 = "blue"

  • "red green blue".drop 50 = ""

πŸ”—def
String.dropWhile (s : String) (p : Char β†’ Bool) : String
String.dropWhile (s : String) (p : Char β†’ Bool) : String

Creates a new string by removing the longest prefix from s in which p returns true for all characters.

Examples:

  • "red green blue".dropWhile (Β·.isLetter) = " green blue"

  • "red green blue".dropWhile (Β·== 'r') = "ed green blue"

  • "red green blue".dropWhile (Β·!= 'n') = "n blue"

  • "red green blue".dropWhile (fun _ => true) = ""

πŸ”—def
String.dropRight (s : String) (n : Nat) : String
String.dropRight (s : String) (n : Nat) : String

Removes the specified number of characters (Unicode code points) from the end of the string.

If n is greater than s.length, returns "".

Examples:

πŸ”—def
String.dropRightWhile (s : String) (p : Char β†’ Bool) : String
String.dropRightWhile (s : String) (p : Char β†’ Bool) : String

Creates a new string by removing the longest suffix from s in which p returns true for all characters.

Examples:

πŸ”—def
String.dropPrefix? (s pre : String) : Option Substring
String.dropPrefix? (s pre : String) : Option Substring

If pre is a prefix of s, returns the remainder. Returns none otherwise.

The string pre is a prefix of s if there exists a t : String such that s = pre ++ t. If so, the result is some t.

Use String.stripPrefix to return the string unchanged when pre is not a prefix.

Examples:

πŸ”—def
String.stripPrefix (s pre : String) : String
String.stripPrefix (s pre : String) : String

If pre is a prefix of s, returns the remainder. Returns s unmodified otherwise.

The string pre is a prefix of s if there exists a t : String such that s = pre ++ t. If so, the result is t. Otherwise, it is s.

Use String.dropPrefix? to return none when pre is not a prefix.

Examples:

πŸ”—def
String.dropSuffix? (s suff : String) : Option Substring
String.dropSuffix? (s suff : String) : Option Substring

If suff is a suffix of s, returns the remainder. Returns none otherwise.

The string suff is a suffix of s if there exists a t : String such that s = t ++ suff. If so, the result is some t.

Use String.stripSuffix to return the string unchanged when suff is not a suffix.

Examples:

πŸ”—def
String.stripSuffix (s suff : String) : String
String.stripSuffix (s suff : String) : String

If suff is a suffix of s, returns the remainder. Returns s unmodified otherwise.

The string suff is a suffix of s if there exists a t : String such that s = t ++ suff. If so, the result is t. Otherwise, it is s.

Use String.dropSuffix? to return none when suff is not a suffix.

Examples:

πŸ”—def
String.trim (s : String) : String
String.trim (s : String) : String

Removes leading and trailing whitespace from a string.

β€œWhitespace” is defined as characters for which Char.isWhitespace returns true.

Examples:

  • "abc".trim = "abc"

  • " abc".trim = "abc"

  • "abc \t ".trim = "abc"

  • " abc ".trim = "abc"

  • "abc\ndef\n".trim = "abc\ndef"

πŸ”—def
String.trimLeft (s : String) : String
String.trimLeft (s : String) : String

Removes leading whitespace from a string.

β€œWhitespace” is defined as characters for which Char.isWhitespace returns true.

Examples:

πŸ”—def
String.trimRight (s : String) : String
String.trimRight (s : String) : String

Removes trailing whitespace from a string.

β€œWhitespace” is defined as characters for which Char.isWhitespace returns true.

Examples:

πŸ”—def
String.removeLeadingSpaces (s : String) : String
String.removeLeadingSpaces (s : String) : String

Consistently de-indents the lines in a string, removing the same amount of leading whitespace from each line such that the least-indented line has no leading whitespace.

The number of leading whitespace characters to remove from each line is determined by counting the number of leading space (' ') and tab ('\t') characters on lines after the first line that also contain non-whitespace characters. No distinction is made between tab and space characters; both count equally.

The least number of leading whitespace characters found is then removed from the beginning of each line. The first line's leading whitespace is not counted when determining how far to de-indent the string, but leading whitespace is removed from it.

Examples:

πŸ”—def
String.set : String β†’ String.Pos.Raw β†’ Char β†’ String
String.set : String β†’ String.Pos.Raw β†’ Char β†’ String

Replaces the character at a specified position in a string with a new character. If the position is invalid, the string is returned unchanged.

If both the replacement character and the replaced character are 7-bit ASCII characters and the string is not shared, then it is updated in-place and not copied.

Examples:

  • "abc".set ⟨1⟩ 'B' = "aBc"

  • "abc".set ⟨3⟩ 'D' = "abc"

  • "Lβˆƒβˆ€N".set ⟨4⟩ 'X' = "LβˆƒXN"

  • "Lβˆƒβˆ€N".set ⟨2⟩ 'X' = "Lβˆƒβˆ€N" because 'βˆƒ' is a multi-byte character, so the byte index 2 is an invalid position.

πŸ”—def
String.modify (s : String) (i : String.Pos.Raw) (f : Char β†’ Char) : String
String.modify (s : String) (i : String.Pos.Raw) (f : Char β†’ Char) : String

Replaces the character at position p in the string s with the result of applying f to that character. If p is an invalid position, the string is returned unchanged.

If both the replacement character and the replaced character are 7-bit ASCII characters and the string is not shared, then it is updated in-place and not copied.

Examples:

πŸ”—def
String.front (s : String) : Char
String.front (s : String) : Char

Returns the first character in s. If s = "", returns (default : Char).

Examples:

πŸ”—def
String.back (s : String) : Char
String.back (s : String) : Char

Returns the last character in s. If s = "", returns (default : Char).

Examples:

πŸ”—def
String.posOf (s : String) (c : Char) : String.Pos.Raw
String.posOf (s : String) (c : Char) : String.Pos.Raw

Returns the position of the first occurrence of a character, c, in a string s. If s does not contain c, returns s.endPos.

Examples:

  • "abcba".posOf 'a' = ⟨0⟩

  • "abcba".posOf 'z' = ⟨5⟩

  • "Lβˆƒβˆ€N".posOf 'βˆ€' = ⟨4⟩

πŸ”—def
String.revPosOf (s : String) (c : Char) : Option String.Pos.Raw
String.revPosOf (s : String) (c : Char) : Option String.Pos.Raw

Returns the position of the last occurrence of a character, c, in a string s. If s does not contain c, returns none.

Examples:

πŸ”—def
String.contains (s : String) (c : Char) : Bool
String.contains (s : String) (c : Char) : Bool

Checks whether a string contains the specified character.

Examples:

πŸ”—def
String.offsetOfPos (s : String) (pos : String.Pos.Raw) : Nat
String.offsetOfPos (s : String) (pos : String.Pos.Raw) : Nat

Returns the character index that corresponds to the provided position (i.e. UTF-8 byte index) in a string.

If the position is at the end of the string, then the string's length in characters is returned. If the position is invalid due to pointing at the middle of a UTF-8 byte sequence, then the character index of the next character after the position is returned.

Examples:

πŸ”—def
String.replace (s pattern replacement : String) : String
String.replace (s pattern replacement : String) : String

In the string s, replaces all occurrences of pattern with replacement.

Examples:

  • "red green blue".replace "e" "" = "rd grn blu"

  • "red green blue".replace "ee" "E" = "red grEn blue"

  • "red green blue".replace "e" "E" = "rEd grEEn bluE"

πŸ”—def
String.findLineStart (s : String) (pos : String.Pos.Raw) : String.Pos.Raw
String.findLineStart (s : String) (pos : String.Pos.Raw) : String.Pos.Raw

Returns the position of the beginning of the line that contains the position pos.

Lines are ended by '\n', and the returned position is either 0 : String.Pos or immediately after a '\n' character.

πŸ”—def
String.find (s : String) (p : Char β†’ Bool) : String.Pos.Raw
String.find (s : String) (p : Char β†’ Bool) : String.Pos.Raw

Finds the position of the first character in a string for which the Boolean predicate p returns true. If there is no such character in the string, then the end position of the string is returned.

Examples:

  • "coffee tea water".find (Β·.isWhitespace) = ⟨6⟩

  • "tea".find (Β·== 'X') = ⟨3⟩

  • "".find (Β·== 'X') = ⟨0⟩

πŸ”—def
String.revFind (s : String) (p : Char β†’ Bool) : Option String.Pos.Raw
String.revFind (s : String) (p : Char β†’ Bool) : Option String.Pos.Raw

Finds the position of the last character in a string for which the Boolean predicate p returns true. If there is no such character in the string, then none is returned.

Examples:

19.8.4.7.Β Folds and AggregationπŸ”—

πŸ”—def
String.map (f : Char β†’ Char) (s : String) : String
String.map (f : Char β†’ Char) (s : String) : String

Applies the function f to every character in a string, returning a string that contains the resulting characters.

Examples:

πŸ”—def
String.foldl.{u} {Ξ± : Type u} (f : Ξ± β†’ Char β†’ Ξ±) (init : Ξ±) (s : String) : Ξ±
String.foldl.{u} {Ξ± : Type u} (f : Ξ± β†’ Char β†’ Ξ±) (init : Ξ±) (s : String) : Ξ±

Folds a function over a string from the left, accumulating a value starting with init. The accumulated value is combined with each character in order, using f.

Examples:

πŸ”—def
String.foldr.{u} {Ξ± : Type u} (f : Char β†’ Ξ± β†’ Ξ±) (init : Ξ±) (s : String) : Ξ±
String.foldr.{u} {Ξ± : Type u} (f : Char β†’ Ξ± β†’ Ξ±) (init : Ξ±) (s : String) : Ξ±

Folds a function over a string from the right, accumulating a value starting with init. The accumulated value is combined with each character in reverse order, using f.

Examples:

πŸ”—def
String.all (s : String) (p : Char β†’ Bool) : Bool
String.all (s : String) (p : Char β†’ Bool) : Bool

Checks whether the Boolean predicate p returns true for every character in a string.

Short-circuits at the first character for which p returns false.

Examples:

πŸ”—def
String.any (s : String) (p : Char β†’ Bool) : Bool
String.any (s : String) (p : Char β†’ Bool) : Bool

Checks whether there is a character in a string for which the Boolean predicate p returns true.

Short-circuits at the first character for which p returns true.

Examples:

19.8.4.8.Β ComparisonsπŸ”—

The LT String instance is defined by the lexicographic ordering on strings based on the LT Char instance. Logically, this is modeled by the lexicographic ordering on the lists that model strings, so List.Lex defines the order. It is decidable, and the decision procedure is overridden at runtime with efficient code that takes advantage of the run-time representation of strings.

πŸ”—def
String.le (a b : String) : Prop
String.le (a b : String) : Prop

Non-strict inequality on strings, typically used via the ≀ operator.

a ≀ b is defined to mean Β¬ b < a.

πŸ”—def
String.firstDiffPos (a b : String) : String.Pos.Raw
String.firstDiffPos (a b : String) : String.Pos.Raw

Returns the first position where the two strings differ.

If one string is a prefix of the other, then the returned position is the end position of the shorter string. If the strings are identical, then their end position is returned.

Examples:

πŸ”—def
String.substrEq (s1 : String) (pos1 : String.Pos.Raw) (s2 : String) (pos2 : String.Pos.Raw) (sz : Nat) : Bool
String.substrEq (s1 : String) (pos1 : String.Pos.Raw) (s2 : String) (pos2 : String.Pos.Raw) (sz : Nat) : Bool

Checks whether substrings of two strings are equal. Substrings are indicated by their starting positions and a size in UTF-8 bytes. Returns false if the indicated substring does not exist in either string.

πŸ”—def
String.isPrefixOf (p s : String) : Bool
String.isPrefixOf (p s : String) : Bool

Checks whether the first string (p) is a prefix of the second (s).

String.startsWith is a version that takes the potential prefix after the string.

Examples:

πŸ”—def
String.startsWith (s pre : String) : Bool
String.startsWith (s pre : String) : Bool

Checks whether the first string (s) begins with the second (pre).

String.isPrefix is a version that takes the potential prefix before the string.

Examples:

πŸ”—def
String.endsWith (s post : String) : Bool
String.endsWith (s post : String) : Bool

Checks whether the first string (s) ends with the second (post).

Examples:

πŸ”—def
String.decEq (s₁ sβ‚‚ : String) : Decidable (s₁ = sβ‚‚)
String.decEq (s₁ sβ‚‚ : String) : Decidable (s₁ = sβ‚‚)

Decides whether two strings are equal. Normally used via the DecidableEq String instance and the = operator.

At runtime, this function is overridden with an efficient native implementation.

πŸ”—opaque
String.hash (s : String) : UInt64
String.hash (s : String) : UInt64

Computes a hash for strings.

19.8.4.9.Β ManipulationπŸ”—

πŸ”—def
String.split (s : String) (p : Char β†’ Bool) : List String
String.split (s : String) (p : Char β†’ Bool) : List String

Splits a string at each character for which p returns true.

The characters that satisfy p are not included in any of the resulting strings. If multiple characters in a row satisfy p, then the resulting list will contain empty strings.

Examples:

  • "coffee tea water".split (Β·.isWhitespace) = ["coffee", "tea", "water"]

  • "coffee tea water".split (Β·.isWhitespace) = ["coffee", "", "tea", "", "water"]

  • "fun x =>\n x + 1\n".split (Β·== '\n') = ["fun x =>", " x + 1", ""]

πŸ”—def
String.splitOn (s : String) (sep : String := " ") : List String
String.splitOn (s : String) (sep : String := " ") : List String

Splits a string s on occurrences of the separator string sep. The default separator is " ".

When sep is empty, the result is [s]. When sep occurs in overlapping patterns, the first match is taken. There will always be exactly n+1 elements in the returned list if there were n non-overlapping matches of sep in the string. The separators are not included in the returned substrings.

Examples:

  • "here is some text ".splitOn = ["here", "is", "some", "text", ""]

  • "here is some text ".splitOn "some" = ["here is ", " text "]

  • "here is some text ".splitOn "" = ["here is some text "]

  • "ababacabac".splitOn "aba" = ["", "bac", "c"]

πŸ”—def
String.push : String β†’ Char β†’ String
String.push : String β†’ Char β†’ String

Adds a character to the end of a string.

The internal implementation uses dynamic arrays and will perform destructive updates if the string is not shared.

Examples:

  • "abc".push 'd' = "abcd"

  • "".push 'a' = "a"

πŸ”—def
String.pushn (s : String) (c : Char) (n : Nat) : String
String.pushn (s : String) (c : Char) (n : Nat) : String

Adds multiple repetitions of a character to the end of a string.

Returns s, with n repetitions of c at the end. Internally, the implementation repeatedly calls String.push, so the string is modified in-place if there is a unique reference to it.

Examples:

  • "indeed".pushn '!' 2 = "indeed!!"

  • "indeed".pushn '!' 0 = "indeed"

  • "".pushn ' ' 4 = " "

πŸ”—def
String.capitalize (s : String) : String
String.capitalize (s : String) : String

Replaces the first character in s with the result of applying Char.toUpper to it. Returns the empty string if the string is empty.

Char.toUpper has no effect on characters outside of the range 'a'–'z'.

Examples:

πŸ”—def
String.decapitalize (s : String) : String
String.decapitalize (s : String) : String

Replaces the first character in s with the result of applying Char.toLower to it. Returns the empty string if the string is empty.

Char.toLower has no effect on characters outside of the range 'A'–'Z'.

Examples:

πŸ”—def
String.toUpper (s : String) : String
String.toUpper (s : String) : String

Replaces each character in s with the result of applying Char.toUpper to it.

Char.toUpper has no effect on characters outside of the range 'a'–'z'.

Examples:

πŸ”—def
String.toLower (s : String) : String
String.toLower (s : String) : String

Replaces each character in s with the result of applying Char.toLower to it.

Char.toLower has no effect on characters outside of the range 'A'–'Z'.

Examples:

19.8.4.10.Β IteratorsπŸ”—

Fundamentally, a String.Iterator is a pair of a string and a valid position in the string. Iterators provide functions for getting the current character (curr), replacing the current character (setCurr), checking whether the iterator can move to the left or the right (hasPrev and hasNext, respectively), and moving the iterator (prev and next, respectively). Clients are responsible for checking whether they've reached the beginning or end of the string; otherwise, the iterator ensures that its position always points at a character.

πŸ”—structure
String.Iterator : Type
String.Iterator : Type

An iterator over the characters (Unicode code points) in a String. Typically created by String.iter.

String iterators pair a string with a valid byte index. This allows efficient character-by-character processing of strings while avoiding the need to manually ensure that byte indices are used with the correct strings.

An iterator is valid if the position i is valid for the string s, meaning 0 ≀ i ≀ s.endPos and i lies on a UTF8 byte boundary. If i = s.endPos, the iterator is at the end of the string.

Most operations on iterators return unspecified values if the iterator is not valid. The functions in the String.Iterator API rule out the creation of invalid iterators, with two exceptions:

  • Iterator.next iter is invalid if iter is already at the end of the string (iter.atEnd is true), and

  • Iterator.forward iter n/Iterator.nextn iter n is invalid if n is strictly greater than the number of remaining characters.

Constructor

String.Iterator.mk

Fields

s : String

The string being iterated over.

i : String.Pos.Raw

The current UTF-8 byte position in the string s.

This position is not guaranteed to be valid for the string. If the position is not valid, then the current character is (default : Char), similar to String.get on an invalid position.

πŸ”—def
String.iter (s : String) : String.Iterator
String.iter (s : String) : String.Iterator

Creates an iterator at the beginning of the string.

πŸ”—def
String.mkIterator (s : String) : String.Iterator
String.mkIterator (s : String) : String.Iterator

Creates an iterator at the beginning of the string.

πŸ”—def
String.Iterator.curr : String.Iterator β†’ Char
String.Iterator.curr : String.Iterator β†’ Char

Gets the character at the iterator's current position.

A run-time bounds check is performed. Use String.Iterator.curr' to avoid redundant bounds checks.

If the position is invalid, returns (default : Char).

πŸ”—def
String.Iterator.curr' (it : String.Iterator) (h : it.hasNext = true) : Char
String.Iterator.curr' (it : String.Iterator) (h : it.hasNext = true) : Char

Gets the character at the iterator's current position.

The proof of it.hasNext ensures that there is, in fact, a character at the current position. This function is faster that String.Iterator.curr due to avoiding a run-time bounds check.

πŸ”—def
String.Iterator.hasNext : String.Iterator β†’ Bool
String.Iterator.hasNext : String.Iterator β†’ Bool

Checks whether the iterator is at or before the string's last character.

πŸ”—def
String.Iterator.next : String.Iterator β†’ String.Iterator
String.Iterator.next : String.Iterator β†’ String.Iterator

Moves the iterator's position forward by one character, unconditionally.

It is only valid to call this function if the iterator is not at the end of the string (i.e. if Iterator.atEnd is false); otherwise, the resulting iterator will be invalid.

πŸ”—def
String.Iterator.next' (it : String.Iterator) (h : it.hasNext = true) : String.Iterator
String.Iterator.next' (it : String.Iterator) (h : it.hasNext = true) : String.Iterator

Moves the iterator's position forward by one character, unconditionally.

The proof of it.hasNext ensures that there is, in fact, a position that's one character forwards. This function is faster that String.Iterator.next due to avoiding a run-time bounds check.

πŸ”—def
String.Iterator.forward : String.Iterator β†’ Nat β†’ String.Iterator
String.Iterator.forward : String.Iterator β†’ Nat β†’ String.Iterator

Moves the iterator's position forward by the specified number of characters.

The resulting iterator is only valid if the number of characters to skip is less than or equal to the number of characters left in the iterator.

πŸ”—def
String.Iterator.nextn : String.Iterator β†’ Nat β†’ String.Iterator
String.Iterator.nextn : String.Iterator β†’ Nat β†’ String.Iterator

Moves the iterator's position forward by the specified number of characters.

The resulting iterator is only valid if the number of characters to skip is less than or equal to the number of characters left in the iterator.

πŸ”—def
String.Iterator.hasPrev : String.Iterator β†’ Bool
String.Iterator.hasPrev : String.Iterator β†’ Bool

Checks whether the iterator is after the beginning of the string.

πŸ”—def
String.Iterator.prev : String.Iterator β†’ String.Iterator
String.Iterator.prev : String.Iterator β†’ String.Iterator

Moves the iterator's position backward by one character, unconditionally.

The position is not changed if the iterator is at the beginning of the string.

πŸ”—def
String.Iterator.prevn : String.Iterator β†’ Nat β†’ String.Iterator
String.Iterator.prevn : String.Iterator β†’ Nat β†’ String.Iterator

Moves the iterator's position back by the specified number of characters, stopping at the beginning of the string.

πŸ”—def
String.Iterator.atEnd : String.Iterator β†’ Bool
String.Iterator.atEnd : String.Iterator β†’ Bool

Checks whether the iterator is past its string's last character.

πŸ”—def
String.Iterator.toEnd : String.Iterator β†’ String.Iterator
String.Iterator.toEnd : String.Iterator β†’ String.Iterator

Moves the iterator's position to the end of the string, just past the last character.

πŸ”—def
String.Iterator.setCurr : String.Iterator β†’ Char β†’ String.Iterator
String.Iterator.setCurr : String.Iterator β†’ Char β†’ String.Iterator

Replaces the current character in the string.

Does nothing if the iterator is at the end of the string. If both the replacement character and the replaced character are 7-bit ASCII characters and the string is not shared, then it is updated in-place and not copied.

πŸ”—def
String.Iterator.find (it : String.Iterator) (p : Char β†’ Bool) : String.Iterator
String.Iterator.find (it : String.Iterator) (p : Char β†’ Bool) : String.Iterator

Moves the iterator forward until the Boolean predicate p returns true for the iterator's current character or until the end of the string is reached. Does nothing if the current character already satisfies p.

πŸ”—def
String.Iterator.foldUntil.{u_1} {Ξ± : Type u_1} (it : String.Iterator) (init : Ξ±) (f : Ξ± β†’ Char β†’ Option Ξ±) : Ξ± Γ— String.Iterator
String.Iterator.foldUntil.{u_1} {Ξ± : Type u_1} (it : String.Iterator) (init : Ξ±) (f : Ξ± β†’ Char β†’ Option Ξ±) : Ξ± Γ— String.Iterator

Iterates over a string, updating a state at each character using the provided function f, until f returns none. Begins with the state init. Returns the state and character for which f returns none.

πŸ”—def
String.Iterator.extract : String.Iterator β†’ String.Iterator β†’ String
String.Iterator.extract : String.Iterator β†’ String.Iterator β†’ String

Extracts the substring between the positions of two iterators. The first iterator's position is the start of the substring, and the second iterator's position is the end.

Returns the empty string if the iterators are for different strings, or if the position of the first iterator is past the position of the second iterator.

πŸ”—def
String.Iterator.remainingToString : String.Iterator β†’ String
String.Iterator.remainingToString : String.Iterator β†’ String

The remaining characters in an iterator, as a string.

πŸ”—def
String.Iterator.remainingBytes : String.Iterator β†’ Nat
String.Iterator.remainingBytes : String.Iterator β†’ Nat

The number of UTF-8 bytes remaining in the iterator.

πŸ”—def
String.Iterator.pos (self : String.Iterator) : String.Pos.Raw
String.Iterator.pos (self : String.Iterator) : String.Pos.Raw

The current UTF-8 byte position in the string s.

This position is not guaranteed to be valid for the string. If the position is not valid, then the current character is (default : Char), similar to String.get on an invalid position.

πŸ”—def
String.Iterator.toString (self : String.Iterator) : String
String.Iterator.toString (self : String.Iterator) : String

The string being iterated over.

19.8.4.11.Β SubstringsπŸ”—

πŸ”—def
String.toSubstring (s : String) : Substring
String.toSubstring (s : String) : Substring

Converts a String into a Substring that denotes the entire string.

πŸ”—def
String.toSubstring' (s : String) : Substring
String.toSubstring' (s : String) : Substring

Converts a String into a Substring that denotes the entire string.

This is a version of String.toSubstring that doesn't have an @[inline] annotation.

πŸ”—structure
Substring : Type
Substring : Type

A region or slice of some underlying string.

A substring contains an string together with the start and end byte positions of a region of interest. Actually extracting a substring requires copying and memory allocation, while many substrings of the same underlying string may exist with very little overhead, and they are more convenient than tracking the bounds by hand.

Using its constructor explicitly, it is possible to construct a Substring in which one or both of the positions is invalid for the string. Many operations will return unexpected or confusing results if the start and stop positions are not valid. For this reason, Substring will be deprecated in favor of String.Slice, which always represents a valid substring.

Constructor

Substring.mk

Fields

str : String

The underlying string.

startPos : String.Pos.Raw

The byte position of the start of the string slice.

stopPos : String.Pos.Raw

The byte position of the end of the string slice.

19.8.4.11.1.Β Properties

πŸ”—def
Substring.isEmpty (ss : Substring) : Bool
Substring.isEmpty (ss : Substring) : Bool

Checks whether a substring is empty.

A substring is empty if its start and end positions are the same.

πŸ”—def
Substring.bsize : Substring β†’ Nat
Substring.bsize : Substring β†’ Nat

The number of bytes used by the string's UTF-8 encoding.

19.8.4.11.2.Β Positions

πŸ”—def
Substring.atEnd : Substring β†’ String.Pos.Raw β†’ Bool
Substring.atEnd : Substring β†’ String.Pos.Raw β†’ Bool

Checks whether a position in a substring is precisely equal to its ending position.

The position is understood relative to the substring's starting position, rather than the underlying string's starting position.

πŸ”—def
Substring.posOf (s : Substring) (c : Char) : String.Pos.Raw
Substring.posOf (s : Substring) (c : Char) : String.Pos.Raw

Returns the substring-relative position of the first occurrence of c in s, or s.bsize if c doesn't occur.

πŸ”—def
Substring.next : Substring β†’ String.Pos.Raw β†’ String.Pos.Raw
Substring.next : Substring β†’ String.Pos.Raw β†’ String.Pos.Raw

Returns the next position in a substring after the given position. If the position is at the end of the substring, it is returned unmodified.

Both the input position and the returned position are interpreted relative to the substring's start position, not the underlying string.

πŸ”—def
Substring.nextn : Substring β†’ Nat β†’ String.Pos.Raw β†’ String.Pos.Raw
Substring.nextn : Substring β†’ Nat β†’ String.Pos.Raw β†’ String.Pos.Raw

Returns the position that's the specified number of characters forward from the given position in a substring. If the end position of the substring is reached, it is returned.

Both the input position and the returned position are interpreted relative to the substring's start position, not the underlying string.

πŸ”—def
Substring.prev : Substring β†’ String.Pos.Raw β†’ String.Pos.Raw
Substring.prev : Substring β†’ String.Pos.Raw β†’ String.Pos.Raw

Returns the previous position in a substring, just prior to the given position. If the position is at the beginning of the substring, it is returned unmodified.

Both the input position and the returned position are interpreted relative to the substring's start position, not the underlying string.

πŸ”—def
Substring.prevn : Substring β†’ Nat β†’ String.Pos.Raw β†’ String.Pos.Raw
Substring.prevn : Substring β†’ Nat β†’ String.Pos.Raw β†’ String.Pos.Raw

Returns the position that's the specified number of characters prior to the given position in a substring. If the start position of the substring is reached, it is returned.

Both the input position and the returned position are interpreted relative to the substring's start position, not the underlying string.

19.8.4.11.3.Β Folds and Aggregation

πŸ”—def
Substring.foldl.{u} {Ξ± : Type u} (f : Ξ± β†’ Char β†’ Ξ±) (init : Ξ±) (s : Substring) : Ξ±
Substring.foldl.{u} {Ξ± : Type u} (f : Ξ± β†’ Char β†’ Ξ±) (init : Ξ±) (s : Substring) : Ξ±

Folds a function over a substring from the left, accumulating a value starting with init. The accumulated value is combined with each character in order, using f.

πŸ”—def
Substring.foldr.{u} {Ξ± : Type u} (f : Char β†’ Ξ± β†’ Ξ±) (init : Ξ±) (s : Substring) : Ξ±
Substring.foldr.{u} {Ξ± : Type u} (f : Char β†’ Ξ± β†’ Ξ±) (init : Ξ±) (s : Substring) : Ξ±

Folds a function over a substring from the right, accumulating a value starting with init. The accumulated value is combined with each character in reverse order, using f.

πŸ”—def
Substring.all (s : Substring) (p : Char β†’ Bool) : Bool
Substring.all (s : Substring) (p : Char β†’ Bool) : Bool

Checks whether the Boolean predicate p returns true for every character in a substring.

Short-circuits at the first character for which p returns false.

πŸ”—def
Substring.any (s : Substring) (p : Char β†’ Bool) : Bool
Substring.any (s : Substring) (p : Char β†’ Bool) : Bool

Checks whether the Boolean predicate p returns true for any character in a substring.

Short-circuits at the first character for which p returns true.

19.8.4.11.4.Β Comparisons

πŸ”—def
Substring.beq (ss1 ss2 : Substring) : Bool
Substring.beq (ss1 ss2 : Substring) : Bool

Checks whether two substrings represent equal strings. Usually accessed via the == operator.

Two substrings do not need to have the same underlying string or the same start and end positions; instead, they are equal if they contain the same sequence of characters.

πŸ”—def
Substring.sameAs (ss1 ss2 : Substring) : Bool
Substring.sameAs (ss1 ss2 : Substring) : Bool

Checks whether two substrings have the same position and content.

The two substrings do not need to have the same underlying string for this check to succeed.

19.8.4.11.5.Β Prefix and Suffix

πŸ”—def
Substring.commonPrefix (s t : Substring) : Substring
Substring.commonPrefix (s t : Substring) : Substring

Returns the longest common prefix of two substrings.

The returned substring uses the same underlying string as s.

πŸ”—def
Substring.commonSuffix (s t : Substring) : Substring
Substring.commonSuffix (s t : Substring) : Substring

Returns the longest common suffix of two substrings.

The returned substring uses the same underlying string as s.

πŸ”—def
Substring.dropPrefix? (s pre : Substring) : Option Substring
Substring.dropPrefix? (s pre : Substring) : Option Substring

If pre is a prefix of s, returns the remainder. Returns none otherwise.

The substring pre is a prefix of s if there exists a t : Substring such that s.toString = pre.toString ++ t.toString. If so, the result is the substring of s without the prefix.

πŸ”—def
Substring.dropSuffix? (s suff : Substring) : Option Substring
Substring.dropSuffix? (s suff : Substring) : Option Substring

If suff is a suffix of s, returns the remainder. Returns none otherwise.

The substring suff is a suffix of s if there exists a t : Substring such that s.toString = t.toString ++ suff.toString. If so, the result the substring of s without the suffix.

19.8.4.11.6.Β Lookups

πŸ”—def
Substring.get : Substring β†’ String.Pos.Raw β†’ Char
Substring.get : Substring β†’ String.Pos.Raw β†’ Char

Returns the character at the given position in the substring.

The position is relative to the substring, rather than the underlying string, and no bounds checking is performed with respect to the substring's end position. If the relative position is not a valid position in the underlying string, the fallback value (default : Char), which is 'A', is returned. Does not panic.

πŸ”—def
Substring.contains (s : Substring) (c : Char) : Bool
Substring.contains (s : Substring) (c : Char) : Bool

Checks whether a substring contains the specified character.

πŸ”—def
Substring.front (s : Substring) : Char
Substring.front (s : Substring) : Char

Returns the first character in the substring.

If the substring is empty, but the substring's start position is a valid position in the underlying string, then the character at the start position is returned. If the substring's start position is not a valid position in the string, the fallback value (default : Char), which is 'A', is returned. Does not panic.

19.8.4.11.7.Β Modifications

πŸ”—def
Substring.drop : Substring β†’ Nat β†’ Substring
Substring.drop : Substring β†’ Nat β†’ Substring

Removes the specified number of characters (Unicode code points) from the beginning of a substring by advancing its start position.

If the substring's end position is reached, the start position is not advanced past it.

πŸ”—def
Substring.dropWhile : Substring β†’ (Char β†’ Bool) β†’ Substring
Substring.dropWhile : Substring β†’ (Char β†’ Bool) β†’ Substring

Removes the longest prefix of a substring in which a Boolean predicate returns true for all characters by moving the substring's start position. The start position is moved to the position of the first character for which the predicate returns false, or to the substring's end position if the predicate always returns true.

πŸ”—def
Substring.dropRight : Substring β†’ Nat β†’ Substring
Substring.dropRight : Substring β†’ Nat β†’ Substring

Removes the specified number of characters (Unicode code points) from the end of a substring by moving its end position towards its start position.

If the substring's start position is reached, the end position is not retracted past it.

πŸ”—def
Substring.dropRightWhile : Substring β†’ (Char β†’ Bool) β†’ Substring
Substring.dropRightWhile : Substring β†’ (Char β†’ Bool) β†’ Substring

Removes the longest suffix of a substring in which a Boolean predicate returns true for all characters by moving the substring's end position. The end position is moved just after the position of the last character for which the predicate returns false, or to the substring's start position if the predicate always returns true.

πŸ”—def
Substring.take : Substring β†’ Nat β†’ Substring
Substring.take : Substring β†’ Nat β†’ Substring

Retains only the specified number of characters (Unicode code points) at the beginning of a substring, by moving its end position towards its start position.

If the substring's start position is reached, the end position is not retracted past it.

πŸ”—def
Substring.takeWhile : Substring β†’ (Char β†’ Bool) β†’ Substring
Substring.takeWhile : Substring β†’ (Char β†’ Bool) β†’ Substring

Retains only the longest prefix of a substring in which a Boolean predicate returns true for all characters by moving the substring's end position towards its start position.

πŸ”—def
Substring.takeRight : Substring β†’ Nat β†’ Substring
Substring.takeRight : Substring β†’ Nat β†’ Substring

Retains only the specified number of characters (Unicode code points) at the end of a substring, by moving its start position towards its end position.

If the substring's end position is reached, the start position is not advanced past it.

πŸ”—def
Substring.takeRightWhile : Substring β†’ (Char β†’ Bool) β†’ Substring
Substring.takeRightWhile : Substring β†’ (Char β†’ Bool) β†’ Substring

Retains only the longest suffix of a substring in which a Boolean predicate returns true for all characters by moving the substring's start position towards its end position.

πŸ”—def
Substring.extract : Substring β†’ String.Pos.Raw β†’ String.Pos.Raw β†’ Substring
Substring.extract : Substring β†’ String.Pos.Raw β†’ String.Pos.Raw β†’ Substring

Returns the region of the substring delimited by the provided start and stop positions, as a substring. The positions are interpreted with respect to the substring's start position, rather than the underlying string.

If the resulting substring is empty, then the resulting substring is a substring of the empty string "". Otherwise, the underlying string is that of the input substring with the beginning and end positions adjusted.

πŸ”—def
Substring.trim : Substring β†’ Substring
Substring.trim : Substring β†’ Substring

Removes leading and trailing whitespace from a substring by first moving its start position to the first non-whitespace character, and then moving its end position to the last non-whitespace character.

If the substring consists only of whitespace, then the resulting substring's start position is moved to its end position.

β€œWhitespace” is defined as characters for which Char.isWhitespace returns true.

Examples:

πŸ”—def
Substring.trimLeft (s : Substring) : Substring
Substring.trimLeft (s : Substring) : Substring

Removes leading whitespace from a substring by moving its start position to the first non-whitespace character, or to its end position if there is no non-whitespace character.

β€œWhitespace” is defined as characters for which Char.isWhitespace returns true.

πŸ”—def
Substring.trimRight (s : Substring) : Substring
Substring.trimRight (s : Substring) : Substring

Removes trailing whitespace from a substring by moving its end position to the last non-whitespace character, or to its start position if there is no non-whitespace character.

β€œWhitespace” is defined as characters for which Char.isWhitespace returns true.

πŸ”—def
Substring.splitOn (s : Substring) (sep : String := " ") : List Substring
Substring.splitOn (s : Substring) (sep : String := " ") : List Substring

Splits a substring s on occurrences of the separator string sep. The default separator is " ".

When sep is empty, the result is [s]. When sep occurs in overlapping patterns, the first match is taken. There will always be exactly n+1 elements in the returned list if there were n non-overlapping matches of sep in the string. The separators are not included in the returned substrings, which are all substrings of s's string.

πŸ”—def
Substring.repair : Substring β†’ Substring
Substring.repair : Substring β†’ Substring

Given a Substring, returns another one which has valid endpoints and represents the same substring according to Substring.toString. (Note, the substring may still be inverted, i.e. beginning greater than end.)

19.8.4.11.8.Β Conversions

πŸ”—def
Substring.toString : Substring β†’ String
Substring.toString : Substring β†’ String

Copies the region of the underlying string pointed to by a substring into a fresh string.

πŸ”—def
Substring.isNat (s : Substring) : Bool
Substring.isNat (s : Substring) : Bool

Checks whether the substring can be interpreted as the decimal representation of a natural number.

A substring can be interpreted as a decimal natural number if it is not empty and all the characters in it are digits.

Use Substring.toNat? to convert such a substring to a natural number.

πŸ”—def
Substring.toNat? (s : Substring) : Option Nat
Substring.toNat? (s : Substring) : Option Nat

Checks whether the substring can be interpreted as the decimal representation of a natural number, returning the number if it can.

A substring can be interpreted as a decimal natural number if it is not empty and all the characters in it are digits.

Use Substring.isNat to check whether the substring is such a substring.

πŸ”—def
Substring.toIterator : Substring β†’ String.Iterator
Substring.toIterator : Substring β†’ String.Iterator

Returns an iterator into the underlying string, at the substring's starting position. The ending position is discarded, so the iterator alone cannot be used to determine whether its current position is within the original substring.

πŸ”—def
Substring.toName (s : Substring) : Lean.Name
Substring.toName (s : Substring) : Lean.Name

Converts a substring to the Lean compiler's representation of names. The resulting name is hierarchical, and the string is split at the dots ('.').

"a.b".toSubstring.toName is the name a.b, not «a.b». For the latter, use Name.mkSimple ∘ Substring.toString.

19.8.4.12.Β String SlicesπŸ”—

πŸ”—structure
String.Slice : Type
String.Slice : Type

A region or slice of some underlying string.

A slice consists of a string together with the start and end byte positions of a region of interest. Actually extracting a substring requires copying and memory allocation, while many slices of the same underlying string may exist with very little overhead. While this could be achieved by tracking the bounds by hand, the slice API is much more convenient.

String.Slice bundles proofs to ensure that the start and end positions always delineate a valid string. For this reason, it should be preferred over Substring.

Constructor

String.Slice.mk

Fields

str : String

The underlying strings.

startInclusive : self.str.ValidPos

The byte position of the start of the string slice.

endExclusive : self.str.ValidPos

The byte position of the end of the string slice.

startInclusive_le_endExclusive : self.startInclusive.offset ≀ self.endExclusive.offset

The slice is not degenerate (but it may be empty).

πŸ”—structure
String.Slice.Pos (s : String.Slice) : Type
String.Slice.Pos (s : String.Slice) : Type

A Slice.Pos s is a byte offset in s together with a proof that this position is at a UTF-8 character boundary.

Constructor

String.Slice.Pos.mk

Fields

offset : String.Pos.Raw

The underlying byte offset of the Slice.Pos.

isValidForSlice : String.Pos.Raw.IsValidForSlice s self.offset

The proof that offset is valid for the string slice s.

19.8.4.12.1.Β API Reference

19.8.4.12.1.1.Β Copying
πŸ”—def
String.Slice.copy (s : String.Slice) : String
String.Slice.copy (s : String.Slice) : String

Creates a String from a String.Slice by copying the bytes.

19.8.4.12.1.2.Β Size
πŸ”—def
String.Slice.isEmpty (s : String.Slice) : Bool
String.Slice.isEmpty (s : String.Slice) : Bool

Checks whether a slice is empty.

Empty slices have utf8ByteSize 0.

Examples:

πŸ”—def
String.Slice.utf8ByteSize (s : String.Slice) : String.Pos.Raw
String.Slice.utf8ByteSize (s : String.Slice) : String.Pos.Raw

The number of bytes of the UTF-8 encoding of the string slice.

19.8.4.12.1.3.Β Boundaries
πŸ”—def
String.Slice.pos (s : String.Slice) (off : String.Pos.Raw) (h : String.Pos.Raw.IsValidForSlice s off) : s.Pos
String.Slice.pos (s : String.Slice) (off : String.Pos.Raw) (h : String.Pos.Raw.IsValidForSlice s off) : s.Pos

Constructs a valid position on s from a position and a proof that it is valid.

πŸ”—def
String.Slice.pos! (s : String.Slice) (off : String.Pos.Raw) : s.Pos
String.Slice.pos! (s : String.Slice) (off : String.Pos.Raw) : s.Pos

Constructs a valid position s from a position, panicking if the position is not valid.

πŸ”—def
String.Slice.pos? (s : String.Slice) (off : String.Pos.Raw) : Option s.Pos
String.Slice.pos? (s : String.Slice) (off : String.Pos.Raw) : Option s.Pos

Constructs a valid position on s from a position, returning none if the position is not valid.

πŸ”—def
String.Slice.startPos (s : String.Slice) : s.Pos
String.Slice.startPos (s : String.Slice) : s.Pos

The start position of s, as an s.Pos.

πŸ”—def
String.Slice.endPos (s : String.Slice) : s.Pos
String.Slice.endPos (s : String.Slice) : s.Pos

The past-the-end position of s, as an s.Pos.

19.8.4.12.1.3.1.Β Adjustment
πŸ”—def
String.Slice.replaceStart (s : String.Slice) (pos : s.Pos) : String.Slice
String.Slice.replaceStart (s : String.Slice) (pos : s.Pos) : String.Slice

Given a slice and a valid position within the slice, obtain a new slice on the same underlying string by replacing the start of the slice with the given position.

πŸ”—def
String.Slice.replaceStartEnd (s : String.Slice) (newStart newEnd : s.Pos) (h : newStart.offset ≀ newEnd.offset) : String.Slice
String.Slice.replaceStartEnd (s : String.Slice) (newStart newEnd : s.Pos) (h : newStart.offset ≀ newEnd.offset) : String.Slice

Given a slice and two valid positions within the slice, obtain a new slice on the same underlying string formed by the new bounds.

πŸ”—def
String.Slice.replaceStartEnd! (s : String.Slice) (newStart newEnd : s.Pos) : String.Slice
String.Slice.replaceStartEnd! (s : String.Slice) (newStart newEnd : s.Pos) : String.Slice

Given a slice and two valid positions within the slice, obtain a new slice on the same underlying string formed by the new bounds, or panic if the given end is strictly less than the given start.

πŸ”—def
String.Slice.drop (s : String.Slice) (n : Nat) : String.Slice
String.Slice.drop (s : String.Slice) (n : Nat) : String.Slice

Removes the specified number of characters (Unicode code points) from the start of the slice.

If n is greater than the amount of characters in s, returns an empty slice.

Examples:

  • "red green blue".toSlice.drop 4 == "green blue".toSlice

  • "red green blue".toSlice.drop 10 == "blue".toSlice

  • "red green blue".toSlice.drop 50 == "".toSlice

πŸ”—def
String.Slice.dropEnd (s : String.Slice) (n : Nat) : String.Slice
String.Slice.dropEnd (s : String.Slice) (n : Nat) : String.Slice

Removes the specified number of characters (Unicode code points) from the end of the slice.

If n is greater than the amount of characters in s, returns an empty slice.

Examples:

  • "red green blue".toSlice.dropEnd 5 == "red green".toSlice

  • "red green blue".toSlice.dropEnd 11 == "red".toSlice

  • "red green blue".toSlice.dropEnd 50 == "".toSlice

πŸ”—def
String.Slice.dropEndWhile {ρ : Type} [String.Slice.Pattern.BackwardPattern ρ] (s : String.Slice) (pat : ρ) : String.Slice
String.Slice.dropEndWhile {ρ : Type} [String.Slice.Pattern.BackwardPattern ρ] (s : String.Slice) (pat : ρ) : String.Slice

Creates a new slice that contains the longest suffix of s for which pat matched (potentially repeatedly).

Examples:

πŸ”—def
String.Slice.dropPrefix {ρ : Type} [String.Slice.Pattern.ForwardPattern ρ] (s : String.Slice) (pat : ρ) : String.Slice
String.Slice.dropPrefix {ρ : Type} [String.Slice.Pattern.ForwardPattern ρ] (s : String.Slice) (pat : ρ) : String.Slice

If pat matches a prefix of s, returns the remainder. Returns s unmodified otherwise.

Use String.Slice.dropPrefix? to return none when pat does not match a prefix.

This function is generic over all currently supported patterns.

Examples:

  • "red green blue".toSlice.dropPrefix "red " == "green blue".toSlice

  • "red green blue".toSlice.dropPrefix "reed " == "red green blue".toSlice

  • "red green blue".toSlice.dropPrefix 'r' == "ed green blue".toSlice

  • "red green blue".toSlice.dropPrefix Char.isLower == "ed green blue".toSlice

πŸ”—def
String.Slice.dropPrefix? {ρ : Type} [String.Slice.Pattern.ForwardPattern ρ] (s : String.Slice) (pat : ρ) : Option String.Slice
String.Slice.dropPrefix? {ρ : Type} [String.Slice.Pattern.ForwardPattern ρ] (s : String.Slice) (pat : ρ) : Option String.Slice

If pat matches a prefix of s, returns the remainder. Returns none otherwise.

Use String.Slice.dropPrefix to return the slice unchanged when pat does not match a prefix.

This function is generic over all currently supported patterns.

Examples:

πŸ”—def
String.Slice.dropSuffix {ρ : Type} [String.Slice.Pattern.BackwardPattern ρ] (s : String.Slice) (pat : ρ) : String.Slice
String.Slice.dropSuffix {ρ : Type} [String.Slice.Pattern.BackwardPattern ρ] (s : String.Slice) (pat : ρ) : String.Slice

If pat matches a suffix of s, returns the remainder. Returns s unmodified otherwise.

Use String.Slice.dropSuffix? to return none when pat does not match a prefix.

This function is generic over all currently supported patterns.

Examples:

  • "red green blue".toSlice.dropSuffix " blue" == "red green".toSlice

  • "red green blue".toSlice.dropSuffix "bluu " == "red green blue".toSlice

  • "red green blue".toSlice.dropSuffix 'e' == "red green blu".toSlice

  • "red green blue".toSlice.dropSuffix Char.isLower == "red green blu".toSlice

πŸ”—def
String.Slice.dropSuffix? {ρ : Type} [String.Slice.Pattern.BackwardPattern ρ] (s : String.Slice) (pat : ρ) : Option String.Slice
String.Slice.dropSuffix? {ρ : Type} [String.Slice.Pattern.BackwardPattern ρ] (s : String.Slice) (pat : ρ) : Option String.Slice

If pat matches a suffix of s, returns the remainder. Returns none otherwise.

Use String.Slice.dropSuffix to return the slice unchanged when pat does not match a prefix.

This function is generic over all currently supported patterns.

Examples:

πŸ”—def
String.Slice.dropWhile {ρ : Type} [String.Slice.Pattern.ForwardPattern ρ] (s : String.Slice) (pat : ρ) : String.Slice
String.Slice.dropWhile {ρ : Type} [String.Slice.Pattern.ForwardPattern ρ] (s : String.Slice) (pat : ρ) : String.Slice

Creates a new slice that contains the longest prefix of s for which pat matched (potentially repeatedly).

Examples:

  • "red green blue".toSlice.dropWhile Char.isLower == " green blue".toSlice

  • "red green blue".toSlice.dropWhile 'r' == "ed green blue".toSlice

  • "red red green blue".toSlice.dropWhile "red " == "green blue".toSlice

  • "red green blue".toSlice.dropWhile (fun (_ : Char) => true) == "".toSlice

πŸ”—def
String.Slice.take (s : String.Slice) (n : Nat) : String.Slice
String.Slice.take (s : String.Slice) (n : Nat) : String.Slice

Creates a new slice that contains the first n characters (Unicode code points) of s.

If n is greater than the amount of characters in s, returns s.

Examples:

  • "red green blue".toSlice.take 3 == "red".toSlice

  • "red green blue".toSlice.take 1 == "r".toSlice

  • "red green blue".toSlice.take 0 == "".toSlice

  • "red green blue".toSlice.take 100 == "red green blue".toSlice

πŸ”—def
String.Slice.takeEnd (s : String.Slice) (n : Nat) : String.Slice
String.Slice.takeEnd (s : String.Slice) (n : Nat) : String.Slice

Creates a new slice that contains the last n characters (Unicode code points) of s.

If n is greater than the amount of characters in s, returns s.

Examples:

  • "red green blue".toSlice.takeEnd 4 == "blue".toSlice

  • "red green blue".toSlice.takeEnd 1 == "e".toSlice

  • "red green blue".toSlice.takeEnd 0 == "".toSlice

  • "red green blue".toSlice.takeEnd 100 == "red green blue".toSlice

πŸ”—def
String.Slice.takeEndWhile {ρ : Type} [String.Slice.Pattern.BackwardPattern ρ] (s : String.Slice) (pat : ρ) : String.Slice
String.Slice.takeEndWhile {ρ : Type} [String.Slice.Pattern.BackwardPattern ρ] (s : String.Slice) (pat : ρ) : String.Slice

Creates a new slice that contains the suffix prefix of s for which pat matched (potentially repeatedly).

This function is generic over all currently supported patterns.

Examples:

πŸ”—def
String.Slice.takeWhile {ρ : Type} [String.Slice.Pattern.ForwardPattern ρ] (s : String.Slice) (pat : ρ) : String.Slice
String.Slice.takeWhile {ρ : Type} [String.Slice.Pattern.ForwardPattern ρ] (s : String.Slice) (pat : ρ) : String.Slice

Creates a new slice that contains the longest prefix of s for which pat matched (potentially repeatedly).

This function is generic over all currently supported patterns.

Examples:

19.8.4.12.1.4.Β Characters
πŸ”—def
String.Slice.front (s : String.Slice) : Char
String.Slice.front (s : String.Slice) : Char

Returns the first character in s. If s is empty, returns (default : Char).

Examples:

πŸ”—def
String.Slice.front? (s : String.Slice) : Option Char
String.Slice.front? (s : String.Slice) : Option Char

Returns the first character in s. If s is empty, none.

Examples:

πŸ”—def
String.Slice.back (s : String.Slice) : Char
String.Slice.back (s : String.Slice) : Char

Returns the last character in s. If s is empty, returns (default : Char).

Examples:

πŸ”—def
String.Slice.back? (s : String.Slice) : Option Char
String.Slice.back? (s : String.Slice) : Option Char

Returns the last character in s. If s is empty, returns none.

Examples:

19.8.4.12.1.5.Β Bytes
πŸ”—def
String.Slice.getUTF8Byte (s : String.Slice) (p : String.Pos.Raw) (h : p < s.utf8ByteSize) : UInt8
String.Slice.getUTF8Byte (s : String.Slice) (p : String.Pos.Raw) (h : p < s.utf8ByteSize) : UInt8

Accesses the indicated byte in the UTF-8 encoding of a string slice.

At runtime, this function is implemented by efficient, constant-time code.

πŸ”—def
String.Slice.getUTF8Byte! (s : String.Slice) (p : String.Pos.Raw) : UInt8
String.Slice.getUTF8Byte! (s : String.Slice) (p : String.Pos.Raw) : UInt8

Accesses the indicated byte in the UTF-8 encoding of the string slice, or panics if the position is out-of-bounds.

19.8.4.12.1.6.Β Positions
πŸ”—def
String.Slice.findNextPos (offset : String.Pos.Raw) (s : String.Slice) (_h : offset < s.utf8ByteSize) : s.Pos
String.Slice.findNextPos (offset : String.Pos.Raw) (s : String.Slice) (_h : offset < s.utf8ByteSize) : s.Pos

Given a byte position within a string slice, obtains the smallest valid position that is strictly greater than the given byte position.

19.8.4.12.1.7.Β Searching
πŸ”—def
String.Slice.contains {ρ : Type} {Οƒ : String.Slice β†’ Type} [(s : String.Slice) β†’ Std.Iterators.Iterator (Οƒ s) Id (String.Slice.Pattern.SearchStep s)] [βˆ€ (s : String.Slice), Std.Iterators.Finite (Οƒ s) Id] [String.Slice.Pattern.ToForwardSearcher ρ Οƒ] (s : String.Slice) (pat : ρ) : Bool
String.Slice.contains {ρ : Type} {Οƒ : String.Slice β†’ Type} [(s : String.Slice) β†’ Std.Iterators.Iterator (Οƒ s) Id (String.Slice.Pattern.SearchStep s)] [βˆ€ (s : String.Slice), Std.Iterators.Finite (Οƒ s) Id] [String.Slice.Pattern.ToForwardSearcher ρ Οƒ] (s : String.Slice) (pat : ρ) : Bool

Checks whether a slice has a match of the pattern pat anywhere.

This function is generic over all currently supported patterns.

Examples:

πŸ”—def
String.Slice.startsWith {ρ : Type} [String.Slice.Pattern.ForwardPattern ρ] (s : String.Slice) (pat : ρ) : Bool
String.Slice.startsWith {ρ : Type} [String.Slice.Pattern.ForwardPattern ρ] (s : String.Slice) (pat : ρ) : Bool

Checks whether the slice (s) begins with the pattern (pat).

This function is generic over all currently supported patterns.

Examples:

πŸ”—def
String.Slice.endsWith {ρ : Type} [String.Slice.Pattern.BackwardPattern ρ] (s : String.Slice) (pat : ρ) : Bool
String.Slice.endsWith {ρ : Type} [String.Slice.Pattern.BackwardPattern ρ] (s : String.Slice) (pat : ρ) : Bool

Checks whether the slice (s) ends with the pattern (pat).

This function is generic over all currently supported patterns.

Examples:

πŸ”—def
String.Slice.all {ρ : Type} [String.Slice.Pattern.ForwardPattern ρ] (s : String.Slice) (pat : ρ) : Bool
String.Slice.all {ρ : Type} [String.Slice.Pattern.ForwardPattern ρ] (s : String.Slice) (pat : ρ) : Bool

Checks whether a slice only consists of matches of the pattern pat anywhere.

Short-circuits at the first pattern mis-match.

This function is generic over all currently supported patterns.

Examples:

πŸ”—def
String.Slice.find? {ρ : Type} {Οƒ : String.Slice β†’ Type} [(s : String.Slice) β†’ Std.Iterators.Iterator (Οƒ s) Id (String.Slice.Pattern.SearchStep s)] [βˆ€ (s : String.Slice), Std.Iterators.Finite (Οƒ s) Id] [String.Slice.Pattern.ToForwardSearcher ρ Οƒ] (s : String.Slice) (pat : ρ) : Option s.Pos
String.Slice.find? {ρ : Type} {Οƒ : String.Slice β†’ Type} [(s : String.Slice) β†’ Std.Iterators.Iterator (Οƒ s) Id (String.Slice.Pattern.SearchStep s)] [βˆ€ (s : String.Slice), Std.Iterators.Finite (Οƒ s) Id] [String.Slice.Pattern.ToForwardSearcher ρ Οƒ] (s : String.Slice) (pat : ρ) : Option s.Pos

Finds the position of the first match of the pattern pat in a slice true. If there is no match none is returned.

This function is generic over all currently supported patterns.

Examples:

πŸ”—def
String.Slice.revFind? {Οƒ : String.Slice β†’ Type} [(s : String.Slice) β†’ Std.Iterators.Iterator (Οƒ s) Id (String.Slice.Pattern.SearchStep s)] [βˆ€ (s : String.Slice), Std.Iterators.Finite (Οƒ s) Id] {ρ : Type} [String.Slice.Pattern.ToBackwardSearcher ρ Οƒ] (s : String.Slice) (pat : ρ) : Option s.Pos
String.Slice.revFind? {Οƒ : String.Slice β†’ Type} [(s : String.Slice) β†’ Std.Iterators.Iterator (Οƒ s) Id (String.Slice.Pattern.SearchStep s)] [βˆ€ (s : String.Slice), Std.Iterators.Finite (Οƒ s) Id] {ρ : Type} [String.Slice.Pattern.ToBackwardSearcher ρ Οƒ] (s : String.Slice) (pat : ρ) : Option s.Pos

Finds the position of the first match of the pattern pat in a slice true, starting from the end of the slice and traversing towards the start. If there is no match none is returned.

This function is generic over all currently supported patterns except String/String.Slice.

Examples:

19.8.4.12.1.8.Β Manipulation
πŸ”—def
String.Slice.split {ρ : Type} {Οƒ : String.Slice β†’ Type} [String.Slice.Pattern.ToForwardSearcher ρ Οƒ] (s : String.Slice) (pat : ρ) : Std.Iter String.Slice
String.Slice.split {ρ : Type} {Οƒ : String.Slice β†’ Type} [String.Slice.Pattern.ToForwardSearcher ρ Οƒ] (s : String.Slice) (pat : ρ) : Std.Iter String.Slice

Splits a slice at each subslice that matches the pattern pat.

The subslices that matched the pattern are not included in any of the resulting subslices. If multiple subslices in a row match the pattern, the resulting list will contain empty strings.

This function is generic over all currently supported patterns.

Examples:

  • ("coffee tea water".toSlice.split Char.isWhitespace).allowNontermination.toList == ["coffee".toSlice, "tea".toSlice, "water".toSlice]

  • ("coffee tea water".toSlice.split ' ').allowNontermination.toList == ["coffee".toSlice, "tea".toSlice, "water".toSlice]

  • ("coffee tea water".toSlice.split " tea ").allowNontermination.toList == ["coffee".toSlice, "water".toSlice]

  • ("ababababa".toSlice.split "aba").allowNontermination.toList == ["coffee".toSlice, "water".toSlice]

  • ("baaab".toSlice.split "aa").allowNontermination.toList == ["b".toSlice, "ab".toSlice]

πŸ”—def
String.Slice.splitInclusive {ρ : Type} {Οƒ : String.Slice β†’ Type} [String.Slice.Pattern.ToForwardSearcher ρ Οƒ] (s : String.Slice) (pat : ρ) : Std.Iter String.Slice
String.Slice.splitInclusive {ρ : Type} {Οƒ : String.Slice β†’ Type} [String.Slice.Pattern.ToForwardSearcher ρ Οƒ] (s : String.Slice) (pat : ρ) : Std.Iter String.Slice

Splits a slice at each subslice that matches the pattern pat. Unlike split the matched subslices are included at the end of each subslice.

This function is generic over all currently supported patterns.

Examples:

  • ("coffee tea water".toSlice.splitInclusive Char.isWhitespace).allowNontermination.toList == ["coffee ".toSlice, "tea ".toSlice, "water".toSlice]

  • ("coffee tea water".toSlice.splitInclusive ' ').allowNontermination.toList == ["coffee ".toSlice, "tea ".toSlice, "water".toSlice]

  • ("coffee tea water".toSlice.splitInclusive " tea ").allowNontermination.toList == ["coffee tea ".toSlice, "water".toSlice]

  • ("baaab".toSlice.splitInclusive "aa").allowNontermination.toList == ["baa".toSlice, "ab".toSlice]

πŸ”—def
String.Slice.lines (s : String.Slice) : Std.Iter String.Slice
String.Slice.lines (s : String.Slice) : Std.Iter String.Slice

Creates an iterator over all lines in s with the line ending characters \r\n or \n being stripped.

Examples:

  • "foo\r\nbar\n\nbaz\n".toSlice.lines.allowNontermination.toList == ["foo".toSlice, "bar".toSlice, "".toSlice, "baz".toSlice]

  • "foo\r\nbar\n\nbaz".toSlice.lines.allowNontermination.toList == ["foo".toSlice, "bar".toSlice, "".toSlice, "baz".toSlice]

  • "foo\r\nbar\n\nbaz\r".toSlice.lines.allowNontermination.toList == ["foo".toSlice, "bar".toSlice, "".toSlice, "baz\r".toSlice]

πŸ”—def
String.Slice.replaceEnd (s : String.Slice) (pos : s.Pos) : String.Slice
String.Slice.replaceEnd (s : String.Slice) (pos : s.Pos) : String.Slice

Given a slice and a valid position within the slice, obtain a new slice on the same underlying string by replacing the end of the slice with the given position.

πŸ”—def
String.Slice.trimAscii (s : String.Slice) : String.Slice
String.Slice.trimAscii (s : String.Slice) : String.Slice

Removes leading and trailing whitespace from a slice.

β€œWhitespace” is defined as characters for which Char.isWhitespace returns true.

Examples:

  • "abc".toSlice.trimAscii == "abc".toSlice

  • " abc".toSlice.trimAscii == "abc".toSlice

  • "abc \t ".toSlice.trimAscii == "abc".toSlice

  • " abc ".toSlice.trimAscii == "abc".toSlice

  • "abc\ndef\n".toSlice.trimAscii == "abc\ndef".toSlice

πŸ”—def
String.Slice.trimAsciiEnd (s : String.Slice) : String.Slice
String.Slice.trimAsciiEnd (s : String.Slice) : String.Slice

Removes trailing whitespace from a slice by moving its start position to the first non-whitespace character, or to its end position if there is no non-whitespace character.

β€œWhitespace” is defined as characters for which Char.isWhitespace returns true.

Examples:

πŸ”—def
String.Slice.trimAsciiStart (s : String.Slice) : String.Slice
String.Slice.trimAsciiStart (s : String.Slice) : String.Slice

Removes leading whitespace from a slice by moving its start position to the first non-whitespace character, or to its end position if there is no non-whitespace character.

β€œWhitespace” is defined as characters for which Char.isWhitespace returns true.

Examples:

19.8.4.12.1.9.Β Iteration
πŸ”—def
String.Slice.chars (s : String.Slice) : Std.Iter Char
String.Slice.chars (s : String.Slice) : Std.Iter Char

Creates an iterator over all characters (Unicode code points) in s.

Examples:

  • "abc".toSlice.chars.toList = ['a', 'b', 'c']

  • "abβˆ€c".toSlice.chars.toList = ['a', 'b', 'βˆ€', 'c']

πŸ”—def
String.Slice.revChars (s : String.Slice) : Std.Iter Char
String.Slice.revChars (s : String.Slice) : Std.Iter Char

Creates an iterator over all characters (Unicode code points) in s, starting from the end of the slice and iterating towards the start.

Example:

  • "abc".toSlice.revChars.toList = ['c', 'b', 'a']

  • "abβˆ€c".toSlice.revChars.toList = ['c', 'βˆ€', 'b', 'a']

πŸ”—def
String.Slice.positions (s : String.Slice) : Std.Iter { p // p β‰  s.endPos }
String.Slice.positions (s : String.Slice) : Std.Iter { p // p β‰  s.endPos }

Creates an iterator over all valid positions within {name}s.

Examples

  • {lean}("abc".toSlice.positions.map (fun ⟨p, h⟩ => p.get h) |>.toList) = ['a', 'b', 'c']

  • {lean}("abc".toSlice.positions.map (Β·.val.offset.byteIdx) |>.toList) = [0, 1, 2]

  • {lean}("abβˆ€c".toSlice.positions.map (fun ⟨p, h⟩ => p.get h) |>.toList) = ['a', 'b', 'βˆ€', 'c']

  • {lean}("abβˆ€c".toSlice.positions.map (Β·.val.offset.byteIdx) |>.toList) = [0, 1, 2, 5]

πŸ”—def
String.Slice.revPositions (s : String.Slice) : Std.Iter { p // p β‰  s.endPos }
String.Slice.revPositions (s : String.Slice) : Std.Iter { p // p β‰  s.endPos }

Creates an iterator over all valid positions within {name}s, starting from the last valid position and iterating towards the first one.

Examples

πŸ”—def
String.Slice.bytes (s : String.Slice) : Std.Iter UInt8
String.Slice.bytes (s : String.Slice) : Std.Iter UInt8

Creates an iterator over all bytes in {name}s.

Examples:

  • {lean}"abc".toSlice.bytes.toList = [97, 98, 99]

  • {lean}"abβˆ€c".toSlice.bytes.toList = [97, 98, 226, 136, 128, 99]

πŸ”—def
String.Slice.revBytes (s : String.Slice) : Std.Iter UInt8
String.Slice.revBytes (s : String.Slice) : Std.Iter UInt8

Creates an iterator over all bytes in {name}s, starting from the last one and iterating towards the first one.

Examples:

  • {lean}"abc".toSlice.revBytes.toList = [99, 98, 97]

  • {lean}"abβˆ€c".toSlice.revBytes.toList = [99, 128, 136, 226, 98, 97]

πŸ”—def
String.Slice.revSplit {Οƒ : String.Slice β†’ Type} {ρ : Type} [String.Slice.Pattern.ToBackwardSearcher ρ Οƒ] (s : String.Slice) (pat : ρ) : Std.Iter String.Slice
String.Slice.revSplit {Οƒ : String.Slice β†’ Type} {ρ : Type} [String.Slice.Pattern.ToBackwardSearcher ρ Οƒ] (s : String.Slice) (pat : ρ) : Std.Iter String.Slice

Splits a slice at each subslice that matches the pattern pat, starting from the end of the slice and traversing towards the start.

The subslices that matched the pattern are not included in any of the resulting subslices. If multiple subslices in a row match the pattern, the resulting list will contain empty slices.

This function is generic over all currently supported patterns except String/String.Slice.

Examples:

  • ("coffee tea water".toSlice.revSplit Char.isWhitespace).allowNontermination.toList == ["water".toSlice, "tea".toSlice, "coffee".toSlice]

  • ("coffee tea water".toSlice.revSplit ' ').allowNontermination.toList == ["water".toSlice, "tea".toSlice, "coffee".toSlice]

πŸ”—def
String.Slice.foldl.{u} {Ξ± : Type u} (f : Ξ± β†’ Char β†’ Ξ±) (init : Ξ±) (s : String.Slice) : Ξ±
String.Slice.foldl.{u} {Ξ± : Type u} (f : Ξ± β†’ Char β†’ Ξ±) (init : Ξ±) (s : String.Slice) : Ξ±

Folds a function over a slice from the start, accumulating a value starting with init. The accumulated value is combined with each character in order, using f.

Examples:

πŸ”—def
String.Slice.foldr.{u} {Ξ± : Type u} (f : Char β†’ Ξ± β†’ Ξ±) (init : Ξ±) (s : String.Slice) : Ξ±
String.Slice.foldr.{u} {Ξ± : Type u} (f : Char β†’ Ξ± β†’ Ξ±) (init : Ξ±) (s : String.Slice) : Ξ±

Folds a function over a slice from the end, accumulating a value starting with init. The accumulated value is combined with each character in reverse order, using f.

Examples:

19.8.4.12.1.10.Β Conversions
πŸ”—def
String.Slice.isNat (s : String.Slice) : Bool
String.Slice.isNat (s : String.Slice) : Bool

Checks whether the slice can be interpreted as the decimal representation of a natural number.

A slice can be interpreted as a decimal natural number if it is not empty and all the characters in it are digits.

Use toNat? or toNat! to convert such a slice to a natural number.

Examples:

πŸ”—def
String.Slice.toNat! (s : String.Slice) : Nat
String.Slice.toNat! (s : String.Slice) : Nat

Interprets a slice as the decimal representation of a natural number, returning it. Panics if the slice does not contain a decimal natural number.

A slice can be interpreted as a decimal natural number if it is not empty and all the characters in it are digits.

Use isNat to check whether toNat! would return a value. toNat? is a safer alternative that returns none instead of panicking when the string is not a natural number.

Examples:

πŸ”—def
String.Slice.toNat? (s : String.Slice) : Option Nat
String.Slice.toNat? (s : String.Slice) : Option Nat

Interprets a slice as the decimal representation of a natural number, returning it. Returns none if the slice does not contain a decimal natural number.

A slice can be interpreted as a decimal natural number if it is not empty and all the characters in it are digits.

Use isNat to check whether toNat? would return some. toNat! is an alternative that panics instead of returning none when the slice is not a natural number.

Examples:

19.8.4.12.1.11.Β Equality
πŸ”—def
String.Slice.beq (s1 s2 : String.Slice) : Bool
String.Slice.beq (s1 s2 : String.Slice) : Bool

Checks whether s1 and s2 represent the same string, even if they are slices of different base strings or different slices within the same string.

The implementation is an efficient equivalent of s1.copy == s2.copy

πŸ”—def
String.Slice.eqIgnoreAsciiCase (s1 s2 : String.Slice) : Bool
String.Slice.eqIgnoreAsciiCase (s1 s2 : String.Slice) : Bool

Checks whether s1 == s2 if ASCII upper/lowercase are ignored.

19.8.4.12.2.Β Patterns

String slices feature generalized search patterns. Rather than being defined to work only for characters or for strings, many operations on slices accept arbitrary patterns. New types can be made into patterns by defining instances of the classes in this section. The Lean standard library instances that allow the following types to be used for both forward and backward searching:

Pattern Type

Meaning

Char

Matches the provided character

Char β†’ Bool

Matches any character that satisfies the predicate

String

Matches occurrences of the given string

String.Slice

Matches occurrences of the string represented by the slice

πŸ”—type class
String.Slice.Pattern.ToForwardSearcher (ρ : Type) (Οƒ : outParam (String.Slice β†’ Type)) : Type
String.Slice.Pattern.ToForwardSearcher (ρ : Type) (Οƒ : outParam (String.Slice β†’ Type)) : Type

Provides a conversion from a pattern to an iterator of SearchStep that searches for matches of the pattern from the start towards the end of a Slice.

Instance Constructor

String.Slice.Pattern.ToForwardSearcher.mk

Methods

toSearcher : (s : String.Slice) β†’ ρ β†’ Std.Iter (String.Slice.Pattern.SearchStep s)

Builds an iterator of SearchStep corresponding to matches of pat along the slice s. The SearchSteps returned by this iterator must contain ranges that are adjacent, non-overlapping and cover all of s.

πŸ”—type class
String.Slice.Pattern.ForwardPattern (ρ : Type) : Type
String.Slice.Pattern.ForwardPattern (ρ : Type) : Type

Provides simple pattern matching capabilities from the start of a Slice.

While these operations can be implemented on top of ToForwardSearcher some patterns allow for more efficient implementations. This class can be used to specialize for them. If there is no need to specialize in this fashion, then ForwardPattern.defaultImplementation can be used to automatically derive an instance.

Instance Constructor

String.Slice.Pattern.ForwardPattern.mk

Methods

startsWith : String.Slice β†’ ρ β†’ Bool

Checks whether the slice starts with the pattern.

dropPrefix? : String.Slice β†’ ρ β†’ Option String.Slice

Checks whether the slice starts with the pattern. If it does, the slice is returned with the prefix removed; otherwise the result is none.

πŸ”—type class
String.Slice.Pattern.ToBackwardSearcher (ρ : Type) (Οƒ : outParam (String.Slice β†’ Type)) : Type
String.Slice.Pattern.ToBackwardSearcher (ρ : Type) (Οƒ : outParam (String.Slice β†’ Type)) : Type

Provides a conversion from a pattern to an iterator of SearchStep searching for matches of the pattern from the end towards the start of a Slice.

Instance Constructor

String.Slice.Pattern.ToBackwardSearcher.mk

Methods

toSearcher : (s : String.Slice) β†’ ρ β†’ Std.Iter (String.Slice.Pattern.SearchStep s)

Build an iterator of SearchStep corresponding to matches of pat along the slice s. The SearchSteps returned by this iterator must contain ranges that are adjacent, non-overlapping and cover all of s.

πŸ”—type class
String.Slice.Pattern.BackwardPattern (ρ : Type) : Type
String.Slice.Pattern.BackwardPattern (ρ : Type) : Type

Provides simple pattern matching capabilities from the end of a Slice.

While these operations can be implemented on top of ToBackwardSearcher, some patterns allow for more efficient implementations. This class can be used to specialize for them. If there is no need to specialize in this fashion, then BackwardPattern.defaultImplementation can be used to automatically derive an instance.

Instance Constructor

String.Slice.Pattern.BackwardPattern.mk

Methods

endsWith : String.Slice β†’ ρ β†’ Bool

Checks whether the slice ends with the pattern.

dropSuffix? : String.Slice β†’ ρ β†’ Option String.Slice

Checks whether the slice ends with the pattern. If it does, the slice is returned with the suffix removed; otherwise the result is none.

19.8.4.12.3.Β Positions

19.8.4.12.3.1.Β Lookups

Because they retain a reference to the slice from which they were drawn, slice positions allow individual characters or bytes to be looked up.

πŸ”—def
String.Slice.Pos.byte {s : String.Slice} (pos : s.Pos) (h : pos β‰  s.endPos) : UInt8
String.Slice.Pos.byte {s : String.Slice} (pos : s.Pos) (h : pos β‰  s.endPos) : UInt8

Returns the byte at a position in a slice that is not the end position.

πŸ”—def
String.Slice.Pos.get {s : String.Slice} (pos : s.Pos) (h : pos β‰  s.endPos) : Char
String.Slice.Pos.get {s : String.Slice} (pos : s.Pos) (h : pos β‰  s.endPos) : Char

Obtains the character at the given position in the string.

πŸ”—def
String.Slice.Pos.get! {s : String.Slice} (pos : s.Pos) : Char
String.Slice.Pos.get! {s : String.Slice} (pos : s.Pos) : Char

Returns the byte at the given position in the string, or panicks if the position is the end position.

πŸ”—def
String.Slice.Pos.get? {s : String.Slice} (pos : s.Pos) : Option Char
String.Slice.Pos.get? {s : String.Slice} (pos : s.Pos) : Option Char

Returns the byte at the given position in the string, or none if the position is the end position.

19.8.4.12.3.2.Β Incrementing and Decrementing
πŸ”—def
String.Slice.Pos.prev {s : String.Slice} (pos : s.Pos) (h : pos β‰  s.startPos) : s.Pos
String.Slice.Pos.prev {s : String.Slice} (pos : s.Pos) (h : pos β‰  s.startPos) : s.Pos

Returns the previous valid position before the given position, given a proof that the position is not the start position, which guarantees that such a position exists.

πŸ”—def
String.Slice.Pos.prev! {s : String.Slice} (pos : s.Pos) : s.Pos
String.Slice.Pos.prev! {s : String.Slice} (pos : s.Pos) : s.Pos

Returns the previous valid position before the given position, or panics if the position is the start position.

πŸ”—def
String.Slice.Pos.prev? {s : String.Slice} (pos : s.Pos) : Option s.Pos
String.Slice.Pos.prev? {s : String.Slice} (pos : s.Pos) : Option s.Pos

Returns the previous valid position before the given position, or none if the position is the start position.

πŸ”—def
String.Slice.Pos.prevn {s : String.Slice} (p : s.Pos) (n : Nat) : s.Pos
String.Slice.Pos.prevn {s : String.Slice} (p : s.Pos) (n : Nat) : s.Pos

Iterates p.prev n times, saturating at s.startPos if necessary.

πŸ”—def
String.Slice.Pos.next {s : String.Slice} (pos : s.Pos) (h : pos β‰  s.endPos) : s.Pos
String.Slice.Pos.next {s : String.Slice} (pos : s.Pos) (h : pos β‰  s.endPos) : s.Pos

Advances a valid position on a slice to the next valid position, given a proof that the position is not the past-the-end position, which guarantees that such a position exists.

πŸ”—def
String.Slice.Pos.next! {s : String.Slice} (pos : s.Pos) : s.Pos
String.Slice.Pos.next! {s : String.Slice} (pos : s.Pos) : s.Pos

Advances a valid position on a slice to the next valid position, or panics if the given position is the past-the-end position.

πŸ”—def
String.Slice.Pos.next? {s : String.Slice} (pos : s.Pos) : Option s.Pos
String.Slice.Pos.next? {s : String.Slice} (pos : s.Pos) : Option s.Pos

Advances a valid position on a slice to the next valid position, or returns none if the given position is the past-the-end position.

πŸ”—def
String.Slice.Pos.nextn {s : String.Slice} (p : s.Pos) (n : Nat) : s.Pos
String.Slice.Pos.nextn {s : String.Slice} (p : s.Pos) (n : Nat) : s.Pos

Advances the position p n times, saturating at s.endPos if necessary.

19.8.4.12.3.3.Β Other Strings or Slices
πŸ”—def
String.Slice.Pos.cast {s t : String.Slice} (pos : s.Pos) (h : s = t) : t.Pos
String.Slice.Pos.cast {s t : String.Slice} (pos : s.Pos) (h : s = t) : t.Pos

Constructs a valid position on t from a valid position on s and a proof that s = t.

πŸ”—def
String.Slice.Pos.ofSlice {s : String} (pos : s.toSlice.Pos) : s.ValidPos
String.Slice.Pos.ofSlice {s : String} (pos : s.toSlice.Pos) : s.ValidPos

Given a string s, turns a valid position on the slice s.toSlice into a valid position on the string s.

πŸ”—def
String.Slice.Pos.str {s : String.Slice} (pos : s.Pos) : s.str.ValidPos
String.Slice.Pos.str {s : String.Slice} (pos : s.Pos) : s.str.ValidPos

Given a valid position on a slice s, obtains the corresponding valid position on the underlying string s.str.

πŸ”—def
String.Slice.Pos.toCopy {s : String.Slice} (pos : s.Pos) : s.copy.ValidPos
String.Slice.Pos.toCopy {s : String.Slice} (pos : s.Pos) : s.copy.ValidPos

Given a slice s and a position on s, obtain the corresponding position on s.copy.

πŸ”—def
String.Slice.Pos.ofReplaceStart {s : String.Slice} {pβ‚€ : s.Pos} (pos : (s.replaceStart pβ‚€).Pos) : s.Pos
String.Slice.Pos.ofReplaceStart {s : String.Slice} {pβ‚€ : s.Pos} (pos : (s.replaceStart pβ‚€).Pos) : s.Pos

Given a position in s.replaceStart pβ‚€, obtain the corresponding position in s.

πŸ”—def
String.Slice.Pos.toReplaceStart {s : String.Slice} (pβ‚€ pos : s.Pos) (h : pβ‚€.offset ≀ pos.offset) : (s.replaceStart pβ‚€).Pos
String.Slice.Pos.toReplaceStart {s : String.Slice} (pβ‚€ pos : s.Pos) (h : pβ‚€.offset ≀ pos.offset) : (s.replaceStart pβ‚€).Pos

Given a position in s that is at least pβ‚€, obtain the corresponding position in s.replaceStart pβ‚€.

19.8.4.13.Β MetaprogrammingπŸ”—

πŸ”—def
String.toName (s : String) : Lean.Name
String.toName (s : String) : Lean.Name

Converts a string to the Lean compiler's representation of names. The resulting name is hierarchical, and the string is split at the dots ('.').

"a.b".toName is the name a.b, not Β«a.bΒ». For the latter, use Name.mkSimple.

πŸ”—def
String.quote (s : String) : String
String.quote (s : String) : String

Converts a string to its corresponding Lean string literal syntax. Double quotes are added to each end, and internal characters are escaped as needed.

Examples:

19.8.4.14.Β EncodingsπŸ”—

πŸ”—def
String.getUTF8Byte (s : String) (p : String.Pos.Raw) (h : p < s.endPos) : UInt8
String.getUTF8Byte (s : String) (p : String.Pos.Raw) (h : p < s.endPos) : UInt8

Accesses the indicated byte in the UTF-8 encoding of a string.

At runtime, this function is implemented by efficient, constant-time code.

πŸ”—def
String.utf8ByteSize (s : String) : Nat
String.utf8ByteSize (s : String) : Nat

The number of bytes used by the string's UTF-8 encoding.

At runtime, this function takes constant time because the byte length of strings is cached.

πŸ”—def
String.utf8EncodeChar (c : Char) : List UInt8
String.utf8EncodeChar (c : Char) : List UInt8

Returns the sequence of bytes in a character's UTF-8 encoding.

πŸ”—def
String.fromUTF8 (a : ByteArray) (h : a.IsValidUTF8) : String
String.fromUTF8 (a : ByteArray) (h : a.IsValidUTF8) : String

Decodes an array of bytes that encode a string as UTF-8 into the corresponding string.

πŸ”—def
String.fromUTF8? (a : ByteArray) : Option String
String.fromUTF8? (a : ByteArray) : Option String

Decodes an array of bytes that encode a string as UTF-8 into the corresponding string, or returns none if the array is not a valid UTF-8 encoding of a string.

πŸ”—def
String.fromUTF8! (a : ByteArray) : String
String.fromUTF8! (a : ByteArray) : String

Decodes an array of bytes that encode a string as UTF-8 into the corresponding string, or panics if the array is not a valid UTF-8 encoding of a string.

πŸ”—def
String.toUTF8 (a : String) : ByteArray
String.toUTF8 (a : String) : ByteArray

Encodes a string in UTF-8 as an array of bytes.

πŸ”—def
String.crlfToLf (text : String) : String
String.crlfToLf (text : String) : String

Replaces each \r\n with \n to normalize line endings, but does not validate that there are no isolated \r characters.

This is an optimized version of String.replace text "\r\n" "\n".

19.8.5.Β FFIπŸ”—

FFI type
typedef struct {
    lean_object m_header;
    /* byte length including '\0' terminator */
    size_t      m_size;
    size_t      m_capacity;
    /* UTF8 length */
    size_t      m_length;
    char        m_data[0];
} lean_string_object;

The representation of strings in C. See the description of run-time Strings for more details.

FFI function
bool lean_is_string(lean_object * o)

Returns true if o is a string, or false otherwise.

FFI function
lean_string_object * lean_to_string(lean_object * o)

Performs a runtime check that o is indeed a string. If o is not a string, an assertion fails.