String
type String
Implements Monoid, Blankable, Enumerable, Foldable, Truthyable.
reduce Enumerable Foldable
reduce(acc: A, f: (A -> Char -> A)) -> A
Enumerable primitive and string-preserving higher-order operations. The private List intrinsics understand String's [Char] representation; the public methods remain owned here in Kex source.
mapChars
mapChars(f: (Char -> Char)) -> String
No map override: the Enumerable default collects into a list, which is what (Char -> B) -> [B] says. A String-in/String-out mapping is a different operation with a different type, so it gets its own name.
Parameters
f
Examples
"hi".mapChars(&.upperCase) # => "HI"
"hi".map(&.upperCase) # => ['H', 'I'] (a list, per Enumerable)
filter Enumerable
filter(pred: (Char -> Bool)) -> String
first
first : Char?
A String is its OWN type, not a [Char] — chars converts between them. So the sequence operations below are declared here rather than inherited from List, and they answer in String's terms: take/drop/sort hand back a String, while first/last hand back a Char. The List intrinsics they delegate to already understand the String representation, so there is one implementation for both backends.
Returns the first character, or None when the string is empty.
Examples
"hi".first # => Just('h')
"".first # => None
last
last : Char?
Returns the last character, or None when the string is empty.
Examples
"hi".last # => Just('i')
get
get(i: Integer) -> Char?
get(i: Integer, default: Char) -> Char
Returns the character at i, or None when out of range.
Parameters
i
Examples
"hi".get(1) # => 'i'
take
take(n: Integer) -> String
Returns the first n characters.
Parameters
n
Examples
"hello".take(2) # => "he"
drop
drop(n: Integer) -> String
Returns everything after the first n characters.
Parameters
n
Examples
"hello".drop(2) # => "llo"
reject
reject(pred: (Char -> Bool)) -> String
Returns the characters that do NOT satisfy the predicate — filter's complement.
Parameters
pred
Examples
"hello".reject { |c| c == 'l' } # => "heo"
indexOf
indexOf(c: Char) -> Integer?
Returns the index of the first occurrence of c, or None.
Parameters
c
Examples
"hello".indexOf('l') # => 2
findIndex
findIndex(pred: (Char -> Bool)) -> Integer?
Returns the index of the first character satisfying the predicate, or None. Goes through chars because there is no direct intrinsic.
Parameters
pred
Examples
"hello".findIndex { |c| c == 'l' } # => 2
zip
zip(other: [Y]) -> [(Char, Y)]
Pairs each character with the element at the same index in other, stopping at the shorter of the two.
Parameters
other
Examples
"ab".zip([1, 2]) # => [('a', 1), ('b', 2)]
partition
partition(pred: (Char -> Bool)) -> (String, String)
Splits into the characters that satisfy the predicate and those that do not, in that order.
Parameters
pred
Examples
"hello".partition { |c| c == 'l' } # => ("ll", "heo")
count Foldable
count : Integer
Returns the number of characters in the string.
Examples
"hello".count # => 5
"".count # => 0
empty?
empty? : Bool
Returns true if the string contains no characters.
Examples
"".empty? # => true
"hi".empty? # => false
enclose
enclose(wrapper: String) -> String
enclose(left: String, right: String) -> String
Returns an enclosed string, with wrapper on both ends.
Parameters
wrapper- String
Returns String
Examples
"hello".enclose("*") # => "*hello*"
"hello".enclose("__") # => "__hello__"
at
at(i: Integer) -> Char?
Returns the character at position i (0-based), or None if out of range.
Parameters
i
Examples
"hello".at(1) # => Just('e')
"hello".at(9) # => None
chars
chars : [Char]
Returns a list of the individual characters in the string.
Examples
"hi".chars # => ['h', 'i']
bytes
bytes : [Byte]
Returns the string's UTF-8 encoding, one Byte per byte.
chars is the TEXT view of a String and bytes is the STORAGE view, so they differ for anything outside ASCII: "é" is one Char and two Bytes.
Examples
"hi".bytes # => [104, 105]
"é".bytes # => [195, 169]
"é".chars # => ['é']
split
split : [String]
Splits on every occurrence of sep. With no argument, splits into individual characters.
Separator-less: one part per character, as the example above shows. Only the intrinsic had this form, so the walker answered "hi".split with "'this' used outside of a method context" while BEAM returned the parts. Declared BEFORE the separator form, as sort is in list.kex: the walker resolves a no-argument call against the first clause of that name.
Parameters
sep
Examples
"a,b,c".split(",") # => ["a", "b", "c"]
"hi".split # => ["h", "i"]
split(sep: String | Regex) -> [String]
split : [String]
lines
lines : [String]
Splits into lines on \n, dropping a single trailing newline so a file ending in one does not yield a final empty line. Windows line endings are not stripped — split on \r\n explicitly if that matters.
Examples
"a\nb".lines # => ["a", "b"]
"a\nb\n".lines # => ["a", "b"]
"".lines # => []
indentRest
indentRest(prefix: String) -> String
Indents every line but the first by prefix. That is what splicing a multi-line value into an indented ${...} hole needs: the hole's own indentation already covers line one, the rest have to catch up. Blank lines stay blank, and — through lines — one trailing newline is dropped, so a block does not push a stray empty line into its slot.
Parameters
prefix
Examples
"a\nb\n".indentRest(" ") # => "a\n b"
"a".indentRest(" ") # => "a"
replace
replace(pattern: String, replacement: String) -> String
Replaces every literal occurrence of pattern. An empty pattern matches at every character boundary, including both ends.
Parameters
patternreplacement
Examples
"a-b-c".replace("-", "+") # => "a+b+c"
"abc".replace("", "-") # => "-a-b-c-"
substitute
substitute(replacements: {String: String}) -> String
Replaces every key of replacements with its value, in one pass over the map. The keys are the placeholders exactly as written — no syntax is imposed, and nothing is reserved — so $NAME$, __NAME__, {{name}} and %name% are all equally valid, and a template needs no escaping to be a template. $NAME$ is the convention to reach for when there is no reason to prefer another.
Note that a placeholder is NOT ${name}: that is interpolation, which the compiler resolves before this ever sees the string.
This is what a template wants instead of a chain of .replace calls: the chain reads as a pipeline when it is really a substitution table, and it quietly depends on its own order, since an earlier replacement's OUTPUT is still visible to every later one.
Substitutions are applied in the map's canonical key order and each is applied to the result of the last, so a value that itself contains a key can still be rewritten by a later one. Keep values placeholder-free when that matters.
Parameters
replacements
Examples
"Hello, $WHO$!".substitute({"$WHO$": "world"}) # => "Hello, world!"
"$A$ and $B$".substitute({"$A$": "x", "$B$": "y"}) # => "x and y"
"__A__".substitute({"__A__": "any key works"}) # => "any key works"
upperCase
upperCase : String
Returns the string with all characters converted to upper case.
Examples
"hello".upperCase # => "HELLO"
lowerCase
lowerCase : String
Returns the string with all characters converted to lower case.
Examples
"HELLO".lowerCase # => "hello"
capitalize
capitalize : String
Returns the string with its first character upper-cased and the rest LOWER-cased, matching Ruby's String#capitalize — so "hELLO" becomes "Hello", not "HELLO". Unlike upperCase, which shouts the whole string.
Needed to build type names from data: a generated type %name = ... inside a compiled do block requires an upper-case identifier, so a list of lower-case words has to be capitalized first.
Examples
"hello".capitalize # => "Hello"
"hELLO".capitalize # => "Hello" (tail is lower-cased)
"already Capital".capitalize # => "Already capital"
"".capitalize # => ""
reverse
reverse : String
Returns the string with its characters in reverse order.
Examples
"hello".reverse # => "olleh"
contains?
contains?(sub: String) -> Bool
Returns true if sub appears anywhere within the string.
Parameters
sub
Examples
"hello world".contains?("world") # => true
"hello world".contains?("xyz") # => false
startsWith?
startsWith?(prefix: String) -> Bool
Returns true if the string begins with prefix.
Parameters
prefix
Examples
"hello".startsWith?("hel") # => true
"hello".startsWith?("llo") # => false
From Monoid
repeat- Combines this value with itself
ntimes.
From Enumerable
map- Transforms each item by applying
f, collecting the results into a list. mapIndexed- Transforms each item together with its 0-based position, collecting the results into a list.
flatMap- Maps each item to a list and concatenates the results.
collect- Maps each item through
f(returning anOptional), keeping and unwrapping theJust(y)results and droppingNone.
From Foldable
each- Applies
fto each item for its side effects. eachIndexed- Applies
fto each item together with its 0-based position, for side effects. all?- True if every item satisfies
pred. any?- True if at least one item satisfies
pred. find- The first item satisfying
predwrapped in Just, or None.
Defined in other modules
type Char
string
string : String
A Char and a String are distinct types, so converting between them is explicit. to(String) is the fallible protocol and answers String? like every other conversion; string is the total one, because a character is always one character of text and has no failure case to report. It is the single-character counterpart of String.chars and [Char].join("").
'a'.string # => "a"
'a'.to(String) # => Just("a")
"hi".chars.map(&.string) # => ["h", "i"]
module String
fromCodepoint
fromCodepoint(value: Integer) -> String?
Constructs a one-codepoint UTF-8 string. Surrogates and values outside the Unicode scalar range return None.
fromBytes
fromBytes(values: [Byte]) -> String?
Rebuilds a String from its UTF-8 bytes — the inverse of bytes. A String is TEXT, so bytes outside 0..255 or a malformed encoding return None rather than a string that would decode to replacement characters.
String.fromBytes([104, 105]) # => Just("hi")
String.fromBytes([195, 169]) # => Just("é")
String.fromBytes([255]) # => None
type Tuple
items
items : [Any]
Returns the tuple's elements as a list.
A tuple is not a list — its arity is part of its type — so the List methods do not apply to it. This is the explicit conversion.
Examples
(1, "a").items # => [1, "a"]