Equations
- String.instOfNatPos = { ofNat := { byteIdx := 0 } }
Equations
- String.instLTString = { lt := fun (s₁ s₂ : String) => s₁.data < s₂.data }
Equations
- String.decLt s₁ s₂ = List.hasDecidableLt s₁.data s₂.data
Equations
- String.length x = match x with | { data := s } => List.length s
The internal implementation uses dynamic arrays and will perform destructive updates if the String is not shared.
Equations
- String.push x✝ x = match x✝, x with | { data := s }, c => { data := s ++ [c] }
The internal implementation uses dynamic arrays and will perform destructive updates if the String is not shared.
Equations
- String.append x✝ x = match x✝, x with | { data := a }, { data := b } => { data := a ++ b }
O(n) in the runtime, where n is the length of the String
Equations
- String.toList s = s.data
Equations
- String.utf8GetAux [] x✝ x = default
- String.utf8GetAux (c :: cs) x✝ x = if x✝ = x then c else String.utf8GetAux cs (x✝ + c) x
Return character at position p
. If p
is not a valid position
returns (default : Char)
.
See utf8GetAux
for the reference implementation.
Equations
- String.get s p = match s with | { data := s } => String.utf8GetAux s 0 p
Equations
- String.utf8GetAux? [] x✝ x = none
- String.utf8GetAux? (c :: cs) x✝ x = if x✝ = x then some c else String.utf8GetAux? cs (x✝ + c) x
Equations
- String.get? x✝ x = match x✝, x with | { data := s }, p => String.utf8GetAux? s 0 p
Similar to get
, but produces a panic error message if p
is not a valid String.Pos
.
Equations
- String.get! s p = match s with | { data := s } => String.utf8GetAux s 0 p
Equations
- String.utf8SetAux c' [] x✝ x = []
- String.utf8SetAux c' (c :: cs) x✝ x = if x✝ = x then c' :: cs else c :: String.utf8SetAux c' cs (x✝ + c) x
Equations
- String.set x✝¹ x✝ x = match x✝¹, x✝, x with | { data := s }, i, c => { data := String.utf8SetAux c s 0 i }
Equations
- String.modify s i f = String.set s i (f (String.get s i))
Equations
- String.next s p = let c := String.get s p; p + c
Equations
- String.utf8PrevAux [] x✝ x = 0
- String.utf8PrevAux (c :: cs) x✝ x = let i' := x✝ + c; if i' = x then x✝ else String.utf8PrevAux cs i' x
Equations
- String.prev x✝ x = match x✝, x with | { data := s }, p => if p = 0 then 0 else String.utf8PrevAux s 0 p
Equations
- String.back s = String.get s (String.prev s (String.endPos s))
Equations
- String.atEnd x✝ x = match x✝, x with | s, p => decide (p.byteIdx ≥ String.utf8ByteSize s)
Similar to get
but runtime does not perform bounds check.
Equations
- String.get' s p h = match s, h with | { data := s }, h => String.utf8GetAux s 0 p
Similar to next
but runtime does not perform bounds check.
Equations
- String.next' s p h = let c := String.get s p; p + c
Equations
- One or more equations did not get rendered due to their size.
Equations
- String.posOf s c = String.posOfAux s c (String.endPos s) 0
Equations
- One or more equations did not get rendered due to their size.
Equations
- String.revPosOf s c = String.revPosOfAux s c (String.endPos s)
Equations
- One or more equations did not get rendered due to their size.
Equations
- String.find s p = String.findAux s p (String.endPos s) 0
Equations
- String.revFindAux s p pos = if h : pos = 0 then none else let_fun this := ⋯; let pos := String.prev s pos; if p (String.get s pos) = true then some pos else String.revFindAux s p pos
Equations
- String.revFind s p = String.revFindAux s p (String.endPos s)
Equations
- String.Pos.min p₁ p₂ = { byteIdx := Nat.min p₁.byteIdx p₂.byteIdx }
Returns the first position where the two strings differ.
Equations
- String.firstDiffPos a b = let stopPos := String.Pos.min (String.endPos a) (String.endPos b); String.firstDiffPos.loop a b stopPos 0
Equations
- One or more equations did not get rendered due to their size.
Equations
- String.extract x✝¹ x✝ x = match x✝¹, x✝, x with | { data := s }, b, e => if b.byteIdx ≥ e.byteIdx then "" else { data := String.extract.go₁ s 0 b e }
Equations
- String.extract.go₁ [] x✝¹ x✝ x = []
- String.extract.go₁ (c :: cs) x✝¹ x✝ x = if x✝¹ = x✝ then String.extract.go₂ (c :: cs) x✝¹ x else String.extract.go₁ cs (x✝¹ + c) x✝ x
Equations
- String.extract.go₂ [] x✝ x = []
- String.extract.go₂ (c :: cs) x✝ x = if x✝ = x then [] else c :: String.extract.go₂ cs (x✝ + c) x
Equations
- One or more equations did not get rendered due to their size.
Equations
- String.split s p = String.splitAux s p 0 0 []
Equations
- One or more equations did not get rendered due to their size.
Equations
- String.splitOn s sep = if (sep == "") = true then [s] else String.splitOnAux s sep 0 0 0 []
Equations
- String.instInhabitedString = { default := "" }
Equations
- String.instAppendString = { append := String.append }
Equations
- String.pushn s c n = Nat.repeat (fun (s : String) => String.push s c) n s
Equations
- String.join l = List.foldl (fun (r s : String) => r ++ s) "" l
Equations
- String.intercalate s x = match x with | [] => "" | a :: as => String.intercalate.go a s as
Equations
- String.intercalate.go acc s (a :: as) = String.intercalate.go (acc ++ s ++ a) s as
- String.intercalate.go acc s [] = acc
Iterator over the characters (Char
) of a String
.
Typically created by s.iter
, where s
is a String
.
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 arbitrary values if the iterator is not valid. The functions in
the String.Iterator
API should rule out the creation of invalid iterators, with two exceptions:
Iterator.next iter
is invalid ifiter
is already at the end of the string (iter.atEnd
istrue
), andIterator.forward iter n
/Iterator.nextn iter n
is invalid ifn
is strictly greater than the number of remaining characters.
- s : String
The string the iterator is for.
- i : String.Pos
The current position.
This position is not necessarily valid for the string, for instance if one keeps calling
Iterator.next
whenIterator.atEnd
is true. If the position is not valid, then the current character is(default : Char)
, similar toString.get
on an invalid position.
Creates an iterator at the beginning of a string.
Equations
- String.mkIterator s = { s := s, i := 0 }
Creates an iterator at the beginning of a string.
Equations
The size of a string iterator is the number of bytes remaining.
Equations
- String.instSizeOfIterator = { sizeOf := fun (i : String.Iterator) => String.utf8ByteSize i.s - i.i.byteIdx }
The string the iterator is for.
Equations
Number of bytes remaining in the iterator.
Equations
- String.Iterator.remainingBytes x = match x with | { s := s, i := i } => (String.endPos s).byteIdx - i.byteIdx
The current position.
This position is not necessarily valid for the string, for instance if one keeps calling
Iterator.next
when Iterator.atEnd
is true. If the position is not valid, then the
current character is (default : Char)
, similar to String.get
on an invalid position.
Equations
The character at the current position.
On an invalid position, returns (default : Char)
.
Equations
- String.Iterator.curr x = match x with | { s := s, i := i } => String.get s i
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.
Iterator.atEnd
is false
; otherwise, the resulting iterator will be invalid.
Equations
- String.Iterator.next x = match x with | { s := s, i := i } => { s := s, i := String.next s i }
Decreases the iterator's position.
If the position is zero, this function is the identity.
Equations
- String.Iterator.prev x = match x with | { s := s, i := i } => { s := s, i := String.prev s i }
True if the iterator is past the string's last character.
Equations
- String.Iterator.atEnd x = match x with | { s := s, i := i } => decide (i.byteIdx ≥ (String.endPos s).byteIdx)
True if the iterator is not past the string's last character.
Equations
- String.Iterator.hasNext x = match x with | { s := s, i := i } => decide (i.byteIdx < (String.endPos s).byteIdx)
True if the position is not zero.
Equations
- String.Iterator.hasPrev x = match x with | { s := s, i := i } => decide (i.byteIdx > 0)
Replaces the current character in the string.
Does nothing if the iterator is at the end of the string. If the iterator contains the only reference to its string, this function will mutate the string in-place instead of allocating a new one.
Equations
- String.Iterator.setCurr x✝ x = match x✝, x with | { s := s, i := i }, c => { s := String.set s i c, i := i }
Moves the iterator's position to the end of the string.
Note that i.toEnd.atEnd
is always true
.
Equations
- String.Iterator.toEnd x = match x with | { s := s, i := i } => { s := s, i := String.endPos s }
Extracts the substring between the positions of two iterators.
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.
Equations
- String.Iterator.extract x✝ x = match x✝, x with | { s := s₁, i := b }, { s := s₂, i := e } => if (decide (s₁ ≠ s₂) || decide (b > e)) = true then "" else String.extract s₁ b e
Moves the iterator's position several characters forward.
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.
Equations
The remaining characters in an iterator, as a string.
Equations
- String.Iterator.remainingToString x = match x with | { s := s, i := i } => String.extract s i (String.endPos s)
Moves the iterator's position several characters forward.
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.
Equations
Moves the iterator's position several characters back.
If asked to go back more characters than available, stops at the beginning of the string.
Equations
Equations
- One or more equations did not get rendered due to their size.
Equations
- String.offsetOfPos s pos = String.offsetOfPosAux s pos 0 0
Equations
- String.foldlAux f s stopPos i a = if h : i < stopPos then let_fun this := ⋯; String.foldlAux f s stopPos (String.next s i) (f a (String.get s i)) else a
Equations
- String.foldl f init s = String.foldlAux f s (String.endPos s) 0 init
Equations
- String.foldrAux f a s i begPos = if h : begPos < i then let_fun this := ⋯; let i := String.prev s i; let a := f (String.get s i) a; String.foldrAux f a s i begPos else a
Equations
- String.foldr f init s = String.foldrAux f init s (String.endPos s) 0
Equations
- String.anyAux s stopPos p i = if h : i < stopPos then if p (String.get s i) = true then true else let_fun this := ⋯; String.anyAux s stopPos p (String.next s i) else false
Equations
- String.any s p = String.anyAux s (String.endPos s) p 0
Equations
- String.all s p = !String.any s fun (c : Char) => !p c
Equations
- String.contains s c = String.any s fun (a : Char) => a == c
Equations
- String.mapAux f i s = if h : String.atEnd s i = true then s else let c := f (String.get s i); let_fun this := ⋯; let s := String.set s i c; String.mapAux f (String.next s i) s
Equations
- String.map f s = String.mapAux f 0 s
Equations
- String.isNat s = (!String.isEmpty s && String.all s fun (x : Char) => Char.isDigit x)
Equations
- String.toNat? s = if String.isNat s = true then some (String.foldl (fun (n : Nat) (c : Char) => n * 10 + (Char.toNat c - Char.toNat '0')) 0 s) else none
Return true
iff the substring of byte size sz
starting at position off1
in s1
is equal to that starting at off2
in s2.
.
False if either substring of that byte size does not exist.
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Return true iff p
is a prefix of s
Equations
- String.isPrefixOf p s = String.substrEq p 0 s 0 (String.endPos p).byteIdx
Replace all occurrences of pattern
in s
with replacement
.
Equations
- String.replace s pattern replacement = if h : (String.endPos pattern).byteIdx = 0 then s else let_fun hPatt := ⋯; String.replace.loop s pattern replacement hPatt "" 0 0
Equations
- One or more equations did not get rendered due to their size.
Return the beginning of the line that contains character pos
.
Equations
- String.findLineStart s pos = match String.revFindAux s (fun (x : Char) => decide (x = '\n')) pos with | none => 0 | some n => { byteIdx := n.byteIdx + 1 }
Equations
- Substring.isEmpty ss = (Substring.bsize ss == 0)
Equations
- Substring.toString x = match x with | { str := s, startPos := b, stopPos := e } => String.extract s b e
Equations
- Substring.toIterator x = match x with | { str := s, startPos := b, stopPos := stopPos } => { s := s, i := b }
Return the codepoint at the given offset into the substring.
Equations
- Substring.get x✝ x = match x✝, x with | { str := s, startPos := b, stopPos := stopPos }, p => String.get s (b + p)
Given an offset of a codepoint into the substring, return the offset there of the next codepoint.
Equations
- One or more equations did not get rendered due to their size.
Given an offset of a codepoint into the substring, return the offset there of the previous codepoint.
Equations
- One or more equations did not get rendered due to their size.
Equations
- Substring.nextn x✝ 0 x = x
- Substring.nextn x✝ (Nat.succ i) x = Substring.nextn x✝ i (Substring.next x✝ x)
Equations
- Substring.prevn x✝ 0 x = x
- Substring.prevn x✝ (Nat.succ i) x = Substring.prevn x✝ i (Substring.prev x✝ x)
Equations
- Substring.front s = Substring.get s 0
Return the offset into s
of the first occurrence of c
in s
,
or s.bsize
if c
doesn't occur.
Equations
- Substring.posOf s c = match s with | { str := s, startPos := b, stopPos := e } => { byteIdx := (String.posOfAux s c e b).byteIdx - b.byteIdx }
Equations
- Substring.drop x✝ x = match x✝, x with | ss@h:{ str := s, startPos := b, stopPos := e }, n => { str := s, startPos := b + Substring.nextn ss n 0, stopPos := e }
Equations
- One or more equations did not get rendered due to their size.
Equations
- Substring.take x✝ x = match x✝, x with | ss@h:{ str := s, startPos := b, stopPos := stopPos }, n => { str := s, startPos := b, stopPos := b + Substring.nextn ss n 0 }
Equations
- One or more equations did not get rendered due to their size.
Equations
- Substring.atEnd x✝ x = match x✝, x with | { str := str, startPos := b, stopPos := e }, p => b + p == e
Equations
- One or more equations did not get rendered due to their size.
Equations
- Substring.splitOn s sep = if (sep == "") = true then [s] else Substring.splitOn.loop s sep 0 0 0 []
Equations
- One or more equations did not get rendered due to their size.
Equations
- Substring.foldl f init s = match s with | { str := s, startPos := b, stopPos := e } => String.foldlAux f s e b init
Equations
- Substring.foldr f init s = match s with | { str := s, startPos := b, stopPos := e } => String.foldrAux f init s e b
Equations
- Substring.any s p = match s with | { str := s, startPos := b, stopPos := e } => String.anyAux s e p b
Equations
- Substring.all s p = !Substring.any s fun (c : Char) => !p c
Equations
- Substring.contains s c = Substring.any s fun (a : Char) => a == c
Equations
- One or more equations did not get rendered due to their size.
Equations
- Substring.takeWhile x✝ x = match x✝, x with | { str := s, startPos := b, stopPos := e }, p => let e := Substring.takeWhileAux s e p b; { str := s, startPos := b, stopPos := e }
Equations
- Substring.dropWhile x✝ x = match x✝, x with | { str := s, startPos := b, stopPos := e }, p => let b := Substring.takeWhileAux s e p b; { str := s, startPos := b, stopPos := e }
Equations
- One or more equations did not get rendered due to their size.
Equations
Equations
Equations
- One or more equations did not get rendered due to their size.
Equations
- Substring.isNat s = Substring.all s fun (c : Char) => Char.isDigit c
Equations
- Substring.toNat? s = if Substring.isNat s = true then some (Substring.foldl (fun (n : Nat) (c : Char) => n * 10 + (Char.toNat c - Char.toNat '0')) 0 s) else none
Equations
- Substring.beq ss1 ss2 = (Substring.bsize ss1 == Substring.bsize ss2 && String.substrEq ss1.str ss1.startPos ss2.str ss2.startPos (Substring.bsize ss1))
Equations
- String.drop s n = Substring.toString (Substring.drop (String.toSubstring s) n)
Equations
Equations
- String.take s n = Substring.toString (Substring.take (String.toSubstring s) n)
Equations
Equations
Equations
Equations
Equations
Equations
- String.startsWith s pre = (Substring.take (String.toSubstring s) (String.length pre) == String.toSubstring pre)
Equations
- String.endsWith s post = (Substring.takeRight (String.toSubstring s) (String.length post) == String.toSubstring post)
Equations
Equations
Equations
Equations
- String.nextWhile s p i = Substring.takeWhileAux s (String.endPos s) p i
Equations
- String.nextUntil s p i = String.nextWhile s (fun (c : Char) => !p c) i
Equations
- String.capitalize s = String.set s 0 (Char.toUpper (String.get s 0))
Equations
- String.decapitalize s = String.set s 0 (Char.toLower (String.get s 0))