The Lean Language Reference

18.8.Β StringsπŸ”—

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

  • They have a logical model that specifies their behavior in terms of lists of characters, which specifies the meaning of each operation on strings.

  • They have an optimized run-time representation in compiled code, as packed arrays of bytes that encode the string as UTF-8, and the Lean runtime specially optimizes string operations.

  • There is string literal syntax for writing strings.

The fact that strings are internally represented as 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.Pos, which internally records byte counts rather than character counts, and thus takes constant time. Aside from 0, these should not be constructed directly, but rather updated using String.next and String.prev.

18.8.1.Β Logical Model

πŸ”—structure
String : Type

A string is a sequence of Unicode code points.

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.mk

Pack a List Char into a String. This function is overridden by the compiler and is O(n) in the length of the list.

Fields

data : List Char

Unpack String into a List Char. This function is overridden by the compiler and is O(n) in the length of the list.

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.

18.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.

18.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.

18.8.3.Β SyntaxπŸ”—

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

18.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

18.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.

18.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

18.8.4.Β API ReferenceπŸ”—

18.8.4.1.Β ConstructingπŸ”—

πŸ”—def
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 : String β†’ 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

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

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"

18.8.4.2.Β ConversionsπŸ”—

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

Converts a string to a list of characters.

Even though the logical model of strings is as a structure that wraps a list of characters, this operation takes time and space linear in the length of the string. At runtime, strings are represented as dynamic arrays of bytes.

Examples:

πŸ”—def
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

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

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

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 is not empty, its first character is '-' or a digit, and all subsequent characters are digits. 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

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 is not empty, its first character is either '-' or a digit, and all remaining characters are digits.

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

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 is not empty, its first character is '-' or a digit, and all remaining characters are digits.

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

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

18.8.4.3.Β PropertiesπŸ”—

πŸ”—def
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 : String β†’ Nat

Returns the length of a string in Unicode code points.

Examples:

18.8.4.4.Β PositionsπŸ”—

πŸ”—structure
String.Pos : 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 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.

Constructor

String.Pos.mk

Fields

byteIdx : Nat

Get the underlying byte index of a String.Pos

πŸ”—def
String.Pos.isValid (s : String)
  (p : String.Pos) : 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:

πŸ”—def
String.atEnd : String β†’ String.Pos β†’ 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

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) :
  String.Pos

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

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 where the result is unspecified:

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

  • "Lβˆƒβˆ€N".next ⟨2⟩, 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)
  (h : Β¬s.atEnd p = true) : String.Pos

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) : 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) : String.Pos

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) : String.Pos

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 β†’ String.Pos

Returns the position in a string before a specified position, p. If p = ⟨0⟩, returns 0. If p is not a valid position, the result is unspecified.

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

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.min (p₁ pβ‚‚ : String.Pos) : String.Pos

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

18.8.4.5.Β Lookups and ModificationsπŸ”—

πŸ”—def
String.get (s : String) (p : String.Pos) : 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 β†’ 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) : 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)
  (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) : 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 β†’ String.Pos β†’ 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 ⟨2⟩ ⟨100⟩ = "green blue"

πŸ”—def
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

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

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

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

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

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

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

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

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

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

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

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

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

Removes leading whitespace from a string.

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

Examples:

πŸ”—def
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

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 β†’ 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)
  (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:

  • abc.modify ⟨1⟩ Char.toUpper = "aBc"

  • abc.modify ⟨3⟩ Char.toUpper = "abc"

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

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

Examples:

πŸ”—def
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

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

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

Checks whether a string contains the specified character.

Examples:

πŸ”—def
String.offsetOfPos (s : String)
  (pos : String.Pos) : 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

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) : String.Pos

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

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

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:

18.8.4.6.Β Folds and AggregationπŸ”—

πŸ”—def
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) : Ξ±

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) : Ξ±

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

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

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:

18.8.4.7.Β 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

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

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) (s2 : String)
  (pos2 : String.Pos) (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

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

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

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

Examples:

πŸ”—def
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

Computes a hash for strings.

18.8.4.8.Β ManipulationπŸ”—

πŸ”—def
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

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

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

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

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

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

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

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:

18.8.4.9.Β 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

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

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

Creates an iterator at the beginning of the string.

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

Creates an iterator at the beginning of the string.

πŸ”—def
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.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

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.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

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

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

πŸ”—def
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

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

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

πŸ”—def
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

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.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

The remaining characters in an iterator, as a string.

πŸ”—def
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

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.

18.8.4.10.Β SubstringsπŸ”—

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

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

πŸ”—def
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

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. Instead, it's better to use API functions that ensure the validity of the positions in a substring to create and manipulate them.

Constructor

Substring.mk

Fields

str : String

The underlying string.

startPos : String.Pos

The byte position of the start of the string slice.

stopPos : String.Pos

The byte position of the end of the string slice.

18.8.4.10.1.Β Properties

πŸ”—def
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

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

18.8.4.10.2.Β Positions

πŸ”—def
Substring.atEnd : Substring β†’ String.Pos β†’ 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

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 β†’ String.Pos

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 β†’ String.Pos

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 β†’ String.Pos

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 β†’ String.Pos

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.

18.8.4.10.3.Β Folds and Aggregation

πŸ”—def
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) : Ξ±

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

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

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.

18.8.4.10.4.Β Comparisons

πŸ”—def
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

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.

18.8.4.10.5.Β Prefix and Suffix

πŸ”—def
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

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

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

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.

18.8.4.10.6.Β Lookups

πŸ”—def
Substring.get : Substring β†’ String.Pos β†’ 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

Checks whether a substring contains the specified character.

πŸ”—def
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.

18.8.4.10.7.Β Modifications

πŸ”—def
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

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

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

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

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

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

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

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 β†’ String.Pos β†’ 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

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

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

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

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.

18.8.4.10.8.Β Conversions

πŸ”—def
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

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

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

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

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.

18.8.4.11.Β MetaprogrammingπŸ”—

πŸ”—def
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

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:

18.8.4.12.Β EncodingsπŸ”—

πŸ”—def
String.getUtf8Byte (s : String) (n : Nat)
  (h : n < s.utf8ByteSize) : 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 : 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

Returns the sequence of bytes in a character's UTF-8 encoding.

πŸ”—def
String.utf8DecodeChar? (a : ByteArray)
  (i : Nat) : Option Char

Decodes the UTF-8 character sequence that starts at a given index in a byte array, or none if index i is out of bounds or is not the start of a valid UTF-8 character.

πŸ”—def
String.fromUTF8 (a : ByteArray)
  (h : String.validateUTF8 a = true) : String

Decodes an array of bytes that encode a string as UTF-8 into the corresponding string. Invalid UTF-8 characters in the byte array result in (default : Char), or 'A', in the string.

πŸ”—def
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

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

Encodes a string in UTF-8 as an array of bytes.

πŸ”—def
String.validateUTF8 (a : ByteArray) : Bool

Checks whether an array of bytes is a valid UTF-8 encoding of a string.

πŸ”—def
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".

18.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.