9. Strings and the standard library
The standard library comes in two layers. A few high-frequency names (println,
map/filter/fold, len, to_string, …) live in the prelude and are available
everywhere; everything else lives in a module, brought in with use std/x and
called qualified as x.fn(...) — strings are in std/str, and there are also
std/list, std/map, std/set, std/bytes, std/io and std/cursor. A hot name can
be imported selectively (use std/str.{trim}).
String functions work in code points. str.split separates on a literal, not a
regex; join is its inverse:
use std/str
pub fn main() -> Unit !io = {
let parts = str.split("a,b,c", ",")
println(to_string(len(parts)))
println(join(parts, " - "))
}
Open in playground
3
a - b - c
There are three ways to write a string, and their blind spots complement each other.
Double quotes "..." support escapes and $ interpolation; triple quotes """ span
lines, strip the common indent and need no escaping for quotes (interpolation still
applies); and backticks `...` are a raw string — no escapes, no interpolation,
may span lines, so a regex, a code sample or a fragment of HTML is worth exactly what it
looks like (the one restriction: the content may not contain a backtick):
pub fn main() -> Unit !io = {
println(`"quotes" and $dollar and \n stay literal`)
}
Open in playground
"quotes" and $dollar and \n stay literal
parse_int turns a string into an Option[Int] — failure is None, not an exception:
fn parseOr(s: String, fallback: Int) -> Int =
match parse_int(s) {
Some(n) -> n
None -> fallback
}
pub fn main() -> Unit !io = {
println(to_string(parseOr("42", 0)))
println(to_string(parseOr("oops", -1)))
}
Open in playground
42
-1