Next: strings select, Previous: strings case, Up: strings [Index]
The fundamental string iterator. The string arguments must have the same length.
kons is iterated left–to–right over each index in all of the strings, stopping at the end of the shortest; kons is applied as:
(kons idx state (string-ref str0 idx) (string-ref str idx) ยทยทยท)
where state is the current state value; the current state value begins with knil, and becomes whatever kons returned at the respective iteration; idx is the current index.
string-fold-right
is similar to string-fold
, but it
iterates right–to–left.
Notice that to allow for an unspecified number of arguments, these folds hand the state as first argument to kons, as opposed to the usual fold arguments.
Like string-fold
and string-unfold
but accept strings of
different length, iterating until the end of the shortest one.
Fundamental iterators for substrings. kons is iterated over each character of the selected substring:
(kons (string-ref str (+ start idx)) state)
where state is the current state value; the current state value begins with knil, and becomes whatever kons returned at the respective iteration; idx is the current index.
The left–fold iterator, %substring-fold-left
, builds the return
value as:
(kons (string-ref str (- past 1)) (kons (string-ref str (- past 2)) ... (kons (string-ref str (+ start 2)) (kons (string-ref str (+ start 1)) (kons (string-ref str start) knil)))))
The right–fold iterator, %substring-fold-right
, builds the
return value as:
(kons (string-ref str start (kons (string-ref str (+ start 1)) ... (kons (string-ref str (- past 3)) (kons (string-ref str (- past 2)) (kons (string-ref str (- past 1)) knil)))))
Examples:
;; Convert a string to a list of chars. (substring-fold-left cons '() "abcd") ⇒ (#\d #\c #\b #\a)) ;; Count the number of upper-case characters in a string. (substring-fold-left (lambda (c count) (if (char-upper-case? c) (+ count 1) count)) 0 "ABCdefGHi") ⇒ 5 ;; Double every backslash character in S. (let* ((str "abc\\de\\f\\ghi") (ans-len (string-fold (lambda (c sum) (+ sum (if (char=? c #\\) 2 1))) 0 str)) (ans (make-string ans-len))) (substring-fold-left (lambda (c i) (let ((i (if (char=? c #\\) (begin (string-set! ans i #\\) (+ i 1)) i))) (string-set! ans i c) (+ i 1))) 0 str) ans) ⇒ "abc\\\\de\\\\f\\\\ghi"
This is a fundamental constructor for strings. Arguments description follows.
A map function used to generate a series of “seed” values from the initial seed:
first-seed (make-seed first-seed) ⇒ seed2 (make-seed seed2) ⇒ seed3 (make-seed seed3) ⇒ seed4 ...
A predicate function telling when to stop generating characters; when it returns true when applied to one of the seed values.
Map function mapping each seed value to the corresponding character in the result string. These chars are assembled into the string in a left–to–right order.
An optional string which is used as initial/leftmost portion of the constructed string. Defaults to the empty string.
Optional function applied to the terminal seed value (on which
stop? returns true) to produce the final/rightmost portion of the
constructed string. Defaults to (lambda (x) "")
.
More precisely, the following (simple, inefficient) definitions hold:
;; iterative (define (string-unfold stop? seed->char make-seed first-seed base-string make-final) (let loop ((seed first-seed) (result base-string)) (if (stop? seed) (string-append result (make-final seed)) (loop (make-seed seed) (string-append result (string (seed->char seed))))))) ;; recursive (define (string-unfold stop? seed->char make-seed first-seed base-string make-final) (string-append base-string (let loop ((seed first-seed)) (if (stop? seed) (make-final seed) (string-append (string (seed->char seed)) (loop (make-seed seed)))))))
This function is a fairly powerful string constructor; we can use it to convert a list to a string, read a port into a string, reverse a string, copy a string, and so forth. Examples:
(port->string p) = (string-unfold eof-object? values (lambda (x) (read-char p)) (read-char p)) (list->string lis) = (string-unfold null? car cdr lis) (string-tabulate f size) = (string-unfold (lambda (i) (= i size)) f add1 0)
to map proc
over a list lis, producing a string:
(string-unfold null? (compose proc car) cdr lis)
Interested functional programmers may enjoy noting that
string-fold-right
and string-unfold
are in some sense
inverses. That is, given operations knull?, kar, kdr,
kons, and knil satisfying:
(kons (kar x) (kdr x)) ⇒ x (knull? knil) ⇒ #t
then:
(string-fold-right kons knil (string-unfold knull? kar kdr x)) ⇒ x
and:
(string-unfold knull? kar kdr (string-fold-right kons knil s)) ⇒ s
The final string constructed does not share storage with either base-string or the value produced by make-final.
This is a fundamental constructor for strings. The arguments are like
the ones of string-unfold
. The difference from
string-unfold
is that this function builds the string from right
to left; more precisely, the following (simple, inefficient) definitions
hold:
;; iterative (define (string-unfold-right stop? seed->char make-seed first-seed base-string make-final) (let lp ((seed first-seed) (result base)) (if (stop? seed) (string-append (make-final seed) result) (loop (make-seed seed) (string-append (string (seed->char seed)) result))))) ;; recursive (define (string-unfold-right stop? seed->char make-seed first-seed base-string make-final) (string-append (let loop ((seed first-seed)) (if (stop? seed) (make-final seed) (string-append (loop (make-seed seed)) (string (seed->char seed))))) base))
Interested functional programmers may enjoy noting that
string-fold
and string-unfold-right
are in some sense
inverses. That is, given operations knull?, kar, kdr,
kons, and knil satisfying:
(kons (kar x) (kdr x)) ⇒ x (knull? knil) ⇒ #t
then:
(string-fold kons knil (string-unfold-right knull? kar kdr x)) ⇒ x
and:
(string-unfold-right knull? kar kdr (string-fold kons knil s)) ⇒ s
The final string constructed does not share storage with either base-string or the value produced by make-final.
Next: strings select, Previous: strings case, Up: strings [Index]