Next: srfi strings spec replicate, Previous: srfi strings spec append, Up: srfi strings spec [Index]
proc is a char–to–char procedure and it is mapped over the selected substring of str; return the result string and does not alter its str parameter.
NOTE The order in which proc is applied to the elements of str is not specified.
In–place side–effecting variant.
Apply proc to each character in str from start to end in increasing order. Return unspecified values.
Apply proc to each index of the selected substring of str, in increasing order from start to end. This is simply a method of looping over a string that is guaranteed to be safe and correct. Example:
(let* ((len (string-length s)) (ans (make-string len))) (string-for-each-index (lambda (i) (string-set! ans (- len i) (string-ref s i))) s) ans)
These are the fundamental iterators for strings.
The left–fold operator maps the kons procedure across the string from left to right:
(... (kons s[2] (kons s[1] (kons s[0] knil))))
in other words, string-fold
obeys the (tail) recursion:
(string-fold kons knil s start end) ≡ (string-fold kons (kons s[start] knil) start+1 end)
The right–fold operator maps the kons procedure across the string from right to left:
(kons s[0] (... (kons s[end-3] (kons s[end-2] (kons s[end-1] knil)))))
obeying the (tail) recursion:
(string-fold-right kons knil s start end) ≡ (string-fold-right kons (kons s[end-1] knil) start end-1)
Examples:
;;; Convert a string to a list of chars. (string-fold-right cons '() s) ;;; Count the number of lower-case characters in a string. (string-fold (lambda (c count) (if (char-lower-case? c) (+ count 1) count)) 0 s) ;;; Double every backslash character in S. (let* ((ans-len (string-fold (lambda (c sum) (+ sum (if (char=? c #\\) 2 1))) 0 s)) (ans (make-string ans-len))) (string-fold (lambda (c i) (let ((i (if (char=? c #\\) (begin (string-set! ans i #\\) (+ i 1)) i))) (string-set! ans i c) (+ i 1))) 0 s) ans)
The right–fold combinator is sometimes called a “catamorphism”.
This is a fundamental constructor for strings.
Is 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 ...
Tells us when to stop; when it returns true when applied to one of the seed values.
Maps each seed value to the corresponding character in the result string. These chars are assembled into the string in a left–to–right order.
Is the optional initial/leftmost portion of the constructed string; it defaults to the empty string.
Is applied to the terminal seed value (on which stop? returns true) to produce the final/rightmost portion of the constructed string. It defaults to:
(lambda (x) "")
More precisely, the following (simple, inefficient) definitions hold:
;;; Iterative (define (string-unfold stop? seed->char make-seed first-seed base-str make-final) (let loop ((seed first-seed) (ans base-str)) (if (stop? seed) (string-append ans (make-final seed)) (loop (make-seed seed) (string-append ans (string (seed->char seed))))))) ;;; Recursive (define (string-unfold stop? seed->char make-seed first-seed base-str make-final) (string-append base-str (let recur ((seed first-seed)) (if (stop? seed) (make-final seed) (string-append (string (seed->char seed)) (recur (make-seed seed)))))))
string-unfold
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 seed->char over a list lis, producing a string:
(string-unfold null? (compose f 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-str or the value produced by make-final.
This combinator sometimes is called an “anamorphism”.
This is a fundamental constructor for strings.
Is used to generate a series of “seed” values from the initial first-seed:
first-seed (make-seed first-seed) ⇒ seed2 (make-seed seed2) ⇒ seed3 (make-seed seed3) ⇒ seed4 ...
Tells us when to stop; when it returns true when applied to one of these seed values.
Maps each seed value to the corresponding character in the result string. These chars are assembled into the string in a right–to–left order.
Is the optional initial/rightmost portion of the constructed string; it defaults to the empty string.
Is applied to the terminal seed value (on which stop? returns true) to produce the final/leftmost portion of the constructed string. It defaults to:
(lambda (x) "")
More precisely, the following (simple, inefficient) definitions hold:
;;; Iterative (define (string-unfold-right stop? seed->char make-seed first-seed base-str make-final) (let loop ((seed first-seed) (ans base-str)) (if (stop? seed) (string-append (make-final seed) ans) (loop (make-seed seed) (string-append (string (seed->char seed)) ans))))) ;;; Recursive (define (string-unfold-right stop? seed->char make-seed first-seed base-str make-final) (string-append (let recur ((seed first-seed)) (if (stop? seed) (make-final seed) (string-append (recur (make-seed seed)) (string (seed->char seed))))) base-str))
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-str or the value produced by make-final
.
Next: srfi strings spec replicate, Previous: srfi strings spec append, Up: srfi strings spec [Index]