scheme/mpair
svn: r8151
This commit is contained in:
parent
164f85f288
commit
92ac61e806
|
@ -1,6 +1,7 @@
|
|||
|
||||
(module main scheme/base
|
||||
(require (for-syntax scheme/base)
|
||||
(require scheme/mpair
|
||||
(for-syntax scheme/base)
|
||||
(only-in mzscheme transcript-on transcript-off))
|
||||
|
||||
(provide (for-syntax syntax-rules ...)
|
||||
|
@ -108,50 +109,6 @@
|
|||
caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr
|
||||
cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr)
|
||||
|
||||
(define mmap
|
||||
(case-lambda
|
||||
[(f l) (let loop ([l l])
|
||||
(cond
|
||||
[(null? l) null]
|
||||
[else (mcons (f (mcar l)) (loop (mcdr l)))]))]
|
||||
[(f l1 l2) (let loop ([l1 l1][l2 l2])
|
||||
(cond
|
||||
[(null? l1) null]
|
||||
[else (mcons (f (mcar l1) (mcar l2))
|
||||
(loop (mcdr l1) (mcdr l2)))]))]
|
||||
[(f l . ls) (let loop ([l l][ls ls])
|
||||
(cond
|
||||
[(null? l) null]
|
||||
[else (mcons (apply f (mcar l) (map mcar ls))
|
||||
(loop (mcdr l) (map mcdr ls)))]))]))
|
||||
|
||||
(define mfor-each
|
||||
(case-lambda
|
||||
[(f l) (let loop ([l l])
|
||||
(cond
|
||||
[(null? l) (void)]
|
||||
[else (f (mcar l))
|
||||
(loop (mcdr l))]))]
|
||||
[(f l1 l2) (let loop ([l1 l1][l2 l2])
|
||||
(cond
|
||||
[(null? l1) (void)]
|
||||
[else (f (mcar l1) (mcar l2))
|
||||
(loop (mcdr l1) (mcdr l2))]))]
|
||||
[(f l . ls) (let loop ([l l][ls ls])
|
||||
(cond
|
||||
[(null? l) (void)]
|
||||
[else (apply f (mcar l) (map mcar ls))
|
||||
(loop (mcdr l) (map mcdr ls))]))]))
|
||||
|
||||
(define (list->mlist l)
|
||||
(cond
|
||||
[(null? l) null]
|
||||
[else (mcons (car l) (list->mlist (cdr l)))]))
|
||||
|
||||
(define (mlist->list l)
|
||||
(cond
|
||||
[(null? l) null]
|
||||
[else (cons (mcar l) (mlist->list (mcdr l)))]))
|
||||
|
||||
(define (string->mlist s) (list->mlist (string->list s)))
|
||||
(define (mlist->string s) (list->string (mlist->list s)))
|
||||
|
@ -168,86 +125,6 @@
|
|||
(mlist->list (car l))
|
||||
(cons (car l) (loop (cdr l))))))]))
|
||||
|
||||
(define mlist
|
||||
(case-lambda
|
||||
[() null]
|
||||
[(a) (mcons a null)]
|
||||
[(a b) (mcons a (mcons b null))]
|
||||
[(a b c) (mcons a (mcons b (mcons c null)))]
|
||||
[(a b c d) (mcons a (mcons b (mcons c (mcons d null))))]
|
||||
[l (list->mlist l)]))
|
||||
|
||||
(define (mlist? l)
|
||||
(cond
|
||||
[(null? l) #t]
|
||||
[(mpair? l) (mlist? (mcdr l))]
|
||||
[else #f]))
|
||||
|
||||
(define (mlength l)
|
||||
(let loop ([l l][len 0])
|
||||
(cond
|
||||
[(null? l) len]
|
||||
[else (loop (mcdr l) (add1 len))])))
|
||||
|
||||
(define mappend
|
||||
(case-lambda
|
||||
[() null]
|
||||
[(a) a]
|
||||
[(a b) (let loop ([a a])
|
||||
(if (null? a)
|
||||
b
|
||||
(mcons (mcar a) (loop (mcdr a)))))]
|
||||
[(a . l) (mappend a (apply mappend l))]))
|
||||
|
||||
(define (mreverse l)
|
||||
(let loop ([l l][a null])
|
||||
(cond
|
||||
[(null? l) a]
|
||||
[else (loop (mcdr l) (mcons (mcar l) a))])))
|
||||
|
||||
(define (mlist-tail l n)
|
||||
(cond
|
||||
[(zero? n) l]
|
||||
[else (mlist-tail (mcdr l) (sub1 n))]))
|
||||
|
||||
(define (mlist-ref l n)
|
||||
(cond
|
||||
[(zero? n) (mcar l)]
|
||||
[else (mlist-ref (mcdr l) (sub1 n))]))
|
||||
|
||||
(define (do-member =? v l)
|
||||
(let loop ([l l])
|
||||
(cond
|
||||
[(null? l) #f]
|
||||
[(=? v (mcar l)) l]
|
||||
[else (loop (mcdr l))])))
|
||||
|
||||
(define (mmemq v l)
|
||||
(do-member eq? v l))
|
||||
|
||||
(define (mmemv v l)
|
||||
(do-member eqv? v l))
|
||||
|
||||
(define (mmember v l)
|
||||
(do-member equal? v l))
|
||||
|
||||
|
||||
(define (do-assoc =? v l)
|
||||
(let loop ([l l])
|
||||
(cond
|
||||
[(null? l) #f]
|
||||
[(=? v (mcar (mcar l))) (mcar l)]
|
||||
[else (loop (mcdr l))])))
|
||||
|
||||
(define (massq v l)
|
||||
(do-assoc eq? v l))
|
||||
|
||||
(define (massv v l)
|
||||
(do-assoc eqv? v l))
|
||||
|
||||
(define (massoc v l)
|
||||
(do-assoc equal? v l))
|
||||
|
||||
;; --------------------------------------------------
|
||||
|
||||
(define mread
|
||||
|
|
153
collects/scheme/mpair.ss
Normal file
153
collects/scheme/mpair.ss
Normal file
|
@ -0,0 +1,153 @@
|
|||
#lang scheme/base
|
||||
|
||||
(provide mmap
|
||||
mfor-each
|
||||
mlist
|
||||
mlist?
|
||||
mlength
|
||||
mappend
|
||||
mreverse
|
||||
mlist-tail
|
||||
mlist-ref
|
||||
mmemq
|
||||
mmemv
|
||||
mmember
|
||||
massq
|
||||
massv
|
||||
massoc
|
||||
mlist->list
|
||||
list->mlist
|
||||
mlistof)
|
||||
|
||||
(define mmap
|
||||
(case-lambda
|
||||
[(f l) (let loop ([l l])
|
||||
(cond
|
||||
[(null? l) null]
|
||||
[else (mcons (f (mcar l)) (loop (mcdr l)))]))]
|
||||
[(f l1 l2) (let loop ([l1 l1][l2 l2])
|
||||
(cond
|
||||
[(null? l1) null]
|
||||
[else (mcons (f (mcar l1) (mcar l2))
|
||||
(loop (mcdr l1) (mcdr l2)))]))]
|
||||
[(f l . ls) (let loop ([l l][ls ls])
|
||||
(cond
|
||||
[(null? l) null]
|
||||
[else (mcons (apply f (mcar l) (map mcar ls))
|
||||
(loop (mcdr l) (map mcdr ls)))]))]))
|
||||
|
||||
(define mfor-each
|
||||
(case-lambda
|
||||
[(f l) (let loop ([l l])
|
||||
(cond
|
||||
[(null? l) (void)]
|
||||
[else (f (mcar l))
|
||||
(loop (mcdr l))]))]
|
||||
[(f l1 l2) (let loop ([l1 l1][l2 l2])
|
||||
(cond
|
||||
[(null? l1) (void)]
|
||||
[else (f (mcar l1) (mcar l2))
|
||||
(loop (mcdr l1) (mcdr l2))]))]
|
||||
[(f l . ls) (let loop ([l l][ls ls])
|
||||
(cond
|
||||
[(null? l) (void)]
|
||||
[else (apply f (mcar l) (map mcar ls))
|
||||
(loop (mcdr l) (map mcdr ls))]))]))
|
||||
|
||||
(define (list->mlist l)
|
||||
(cond
|
||||
[(null? l) null]
|
||||
[else (mcons (car l) (list->mlist (cdr l)))]))
|
||||
|
||||
(define (mlist->list l)
|
||||
(cond
|
||||
[(null? l) null]
|
||||
[else (cons (mcar l) (mlist->list (mcdr l)))]))
|
||||
|
||||
(define mlist
|
||||
(case-lambda
|
||||
[() null]
|
||||
[(a) (mcons a null)]
|
||||
[(a b) (mcons a (mcons b null))]
|
||||
[(a b c) (mcons a (mcons b (mcons c null)))]
|
||||
[(a b c d) (mcons a (mcons b (mcons c (mcons d null))))]
|
||||
[l (list->mlist l)]))
|
||||
|
||||
(define (mlist? l)
|
||||
(cond
|
||||
[(null? l) #t]
|
||||
[(mpair? l) (mlist? (mcdr l))]
|
||||
[else #f]))
|
||||
|
||||
(define (mlength l)
|
||||
(let loop ([l l][len 0])
|
||||
(cond
|
||||
[(null? l) len]
|
||||
[else (loop (mcdr l) (add1 len))])))
|
||||
|
||||
(define mappend
|
||||
(case-lambda
|
||||
[() null]
|
||||
[(a) a]
|
||||
[(a b) (let loop ([a a])
|
||||
(if (null? a)
|
||||
b
|
||||
(mcons (mcar a) (loop (mcdr a)))))]
|
||||
[(a . l) (mappend a (apply mappend l))]))
|
||||
|
||||
(define (mreverse l)
|
||||
(let loop ([l l][a null])
|
||||
(cond
|
||||
[(null? l) a]
|
||||
[else (loop (mcdr l) (mcons (mcar l) a))])))
|
||||
|
||||
(define (mlist-tail l n)
|
||||
(cond
|
||||
[(zero? n) l]
|
||||
[else (mlist-tail (mcdr l) (sub1 n))]))
|
||||
|
||||
(define (mlist-ref l n)
|
||||
(cond
|
||||
[(zero? n) (mcar l)]
|
||||
[else (mlist-ref (mcdr l) (sub1 n))]))
|
||||
|
||||
(define (do-member =? v l)
|
||||
(let loop ([l l])
|
||||
(cond
|
||||
[(null? l) #f]
|
||||
[(=? v (mcar l)) l]
|
||||
[else (loop (mcdr l))])))
|
||||
|
||||
(define (mmemq v l)
|
||||
(do-member eq? v l))
|
||||
|
||||
(define (mmemv v l)
|
||||
(do-member eqv? v l))
|
||||
|
||||
(define (mmember v l)
|
||||
(do-member equal? v l))
|
||||
|
||||
|
||||
(define (do-assoc =? v l)
|
||||
(let loop ([l l])
|
||||
(cond
|
||||
[(null? l) #f]
|
||||
[(=? v (mcar (mcar l))) (mcar l)]
|
||||
[else (loop (mcdr l))])))
|
||||
|
||||
(define (massq v l)
|
||||
(do-assoc eq? v l))
|
||||
|
||||
(define (massv v l)
|
||||
(do-assoc eqv? v l))
|
||||
|
||||
(define (massoc v l)
|
||||
(do-assoc equal? v l))
|
||||
|
||||
(define ((mlistof p?) l)
|
||||
(let loop ([l l])
|
||||
(cond
|
||||
[(null? l) #t]
|
||||
[(not (mpair? l)) #f]
|
||||
[(p? (mcar l)) (loop (mcdr l))]
|
||||
[else #f])))
|
|
@ -1,7 +1,7 @@
|
|||
#lang scribble/doc
|
||||
@require["mz.ss"]
|
||||
|
||||
@title[#:style 'toc]{Primitive Datatypes}
|
||||
@title[#:style 'toc #:tag "data"]{Primitive Datatypes}
|
||||
|
||||
Each of the built-in datatypes comes with a set of procedures for
|
||||
manipulating members of the datatype.
|
||||
|
@ -240,6 +240,9 @@ for each pair of keywords is the same as using
|
|||
@; ----------------------------------------------------------------------
|
||||
@include-section["pairs.scrbl"]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@include-section["mpairs.scrbl"]
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
@section[#:tag "vectors"]{Vectors}
|
||||
|
||||
|
|
156
collects/scribblings/reference/mpairs.scrbl
Normal file
156
collects/scribblings/reference/mpairs.scrbl
Normal file
|
@ -0,0 +1,156 @@
|
|||
#lang scribble/doc
|
||||
@(require "mz.ss"
|
||||
scribble/scheme
|
||||
(for-label scheme/mpair))
|
||||
|
||||
@title[#:tag "mpairs"]{Mutable Pairs and Lists}
|
||||
|
||||
A @deftech{mutable pair} is like a pair created by @scheme[cons], but
|
||||
it supports @scheme[set-mcar!] and @scheme[set-mcdr!] mutation
|
||||
operations to change the parts of the pair (like traditional Lisp and
|
||||
Scheme pairs).
|
||||
|
||||
A @deftech{mutable list} is analogous to a list created with pairs, but
|
||||
instead created with immutable pairs.
|
||||
|
||||
@; ----------------------------------------
|
||||
@section{Mutable Pair Constructors and Selectors}
|
||||
|
||||
@defproc[(mpair? [v any/c]) boolean?]{Returns @scheme[#t] if @scheme[v] is
|
||||
a mutable pair, @scheme[#f] otherwise.}
|
||||
|
||||
@defproc[(mcons [a any/c] [d any/c]) pair?]{Returns a mutable pair whose first
|
||||
element is @scheme[a] and second element is @scheme[d].}
|
||||
|
||||
@defproc[(mcar [p mpair?]) any/c]{Returns the first element of the
|
||||
mutable pair @scheme[p].}
|
||||
|
||||
@defproc[(mcdr [p mpair?]) any/c]{Returns the second element of the
|
||||
mutable pair @scheme[p].}
|
||||
|
||||
|
||||
@defproc[(set-mcar! [p mpair?] [v any/v])
|
||||
void?]{
|
||||
|
||||
Changes the mutable pair @scheme[p] so that its first element is
|
||||
@scheme[v].}
|
||||
|
||||
@defproc[(set-mcdr! [p mpair?] [v any/v])
|
||||
void?]{
|
||||
|
||||
Changes the mutable pair @scheme[p] so that its second element is
|
||||
@scheme[v].}
|
||||
|
||||
@; ----------------------------------------
|
||||
@section{Mutable List Functions}
|
||||
|
||||
@note-lib-only[scheme/mpair]
|
||||
|
||||
For functions described in this section, contracts are not directly
|
||||
enforced. In particular, when a mutable list is expected, supplying
|
||||
any other kind of value (or mutating a value that starts as a list)
|
||||
tends to produce an exception from @scheme[mcar] or @scheme[mcdr].
|
||||
|
||||
@defproc[(mlist? [v any/c]) boolean?]{Returns @scheme[#t] if
|
||||
@scheme[v] is a mutable list: either the empty list, or a mutable
|
||||
pair whose second element is a mutable list.}
|
||||
|
||||
|
||||
@defproc[(mlist [v any/c] ...) mlist?]{Returns a newly allocated
|
||||
mutable list containing the @scheme[v]s as its elements.}
|
||||
|
||||
|
||||
@defproc[(list->mlist [lst list?]) mlist?]{
|
||||
|
||||
Returns a newly allocated mutable list with the same elements as
|
||||
@scheme[lst].}
|
||||
|
||||
|
||||
@defproc[(mlist->list [mlst mlist?]) list?]{
|
||||
|
||||
Returns a newly allocated list with the same elements as
|
||||
@scheme[nlst].}
|
||||
|
||||
|
||||
@defproc[(mlength [mlst mlist?])
|
||||
nonnegative-exact-integer?]{
|
||||
|
||||
Returns the number of elements in @scheme[mlst].}
|
||||
|
||||
|
||||
@defproc[(mlist-ref [mlst mlist?][pos nonnegative-exact-integer?])
|
||||
any/c]{
|
||||
|
||||
Like @scheme[list-ref], but for @tech{mutable lists}.}
|
||||
|
||||
|
||||
@defproc[(mlist-tail [mlst mlist?][pos nonnegative-exact-integer?])
|
||||
any/c]{
|
||||
|
||||
Like @scheme[list-tail], but for @tech{mutable lists}.}
|
||||
|
||||
|
||||
@defproc*[([(mappend [mlst mlist?] ...) mlist?]
|
||||
[(mappend [mlst mlist?] ... [v any/c]) any/c])]{
|
||||
|
||||
Like @scheme[append], but for @tech{mutable lists}.}
|
||||
|
||||
|
||||
@defproc[(mreverse [mlst mlist?]) mlist?]{
|
||||
|
||||
Like @scheme[reverse], but for @tech{mutable lists}.}
|
||||
|
||||
|
||||
@defproc[(mmap [proc procedure?] [mlst mlist?] ...+)
|
||||
mlist?]{
|
||||
|
||||
Like @scheme[map], but for @tech{mutable lists}.}
|
||||
|
||||
|
||||
@defproc[(mfor-each [proc procedure?] [mlst mlist?] ...+)
|
||||
void?]{
|
||||
|
||||
Like @scheme[for-each], but for @tech{mutable lists}.}
|
||||
|
||||
|
||||
@defproc[(mmember [v any/c] [mlst mlist?])
|
||||
(or/c mlist? false/c)]{
|
||||
|
||||
Like @scheme[member], but for @tech{mutable lists}.}
|
||||
|
||||
|
||||
@defproc[(mmemv [v any/c] [mlst mlist?])
|
||||
(or/c mlist? false/c)]{
|
||||
|
||||
Like @scheme[memv], but for @tech{mutable lists}.}
|
||||
|
||||
|
||||
@defproc[(mmemq [v any/c] [mlst mlist?])
|
||||
(or/c list? false/c)]{
|
||||
|
||||
Like @scheme[memq], but for @tech{mutable lists}.}
|
||||
|
||||
|
||||
@defproc[(massoc [v any/c] [mlst (mlistof mpair?)])
|
||||
(or/c mpair? false/c)]{
|
||||
|
||||
Like @scheme[assoc], but for mutable lists of mutable pairs.}
|
||||
|
||||
|
||||
@defproc[(massv [v any/c] [mlst (mlistof mpair?)])
|
||||
(or/c mpair? false/c)]{
|
||||
|
||||
Like @scheme[assv], but for mutable lists of mutable pairs.}
|
||||
|
||||
|
||||
@defproc[(massq [v any/c] [mlst (mlistof mpair?)])
|
||||
(or/c mpair? false/c)]{
|
||||
|
||||
Like @scheme[assq], but for mutable lists of mutable pairs.}
|
||||
|
||||
|
||||
@defproc[(mlistof [pred (any/c . -> . any/c)])
|
||||
(any/c . -> . boolean?)]{
|
||||
|
||||
Returns a procedure that returns @scheme[#t] when given a mutable list
|
||||
for which @scheme[pred] returns a true value for all elements.}
|
|
@ -43,10 +43,23 @@
|
|||
|
||||
@title[#:tag "pairs"]{Pairs and Lists}
|
||||
|
||||
A @deftech{pair} combines exactly two values. The first value is
|
||||
accessed with the @scheme[car] procedure, and the second value is
|
||||
accessed with the @scheme[cdr] procedure. Pairs are not mutable (but
|
||||
see @secref["mpairs"]).
|
||||
|
||||
A @deftech{list} is recursively defined: it is either the constant
|
||||
@scheme[null], or it is a pair whose second value is a list.
|
||||
|
||||
A list can be used as a single-valued sequence (see
|
||||
@secref["sequences"]). The elements of the list serve as elements
|
||||
of the sequence. See also @scheme[in-list].
|
||||
|
||||
Cyclic data structures can be created using only immutable pairs via
|
||||
@scheme[read] or @scheme[make-reader-graph]. If starting with a pair
|
||||
and using some number of @scheme[cdr]s returns to the starting pair,
|
||||
then the pair is not a list.
|
||||
|
||||
@; ----------------------------------------
|
||||
@section{Pair Constructors and Selectors}
|
||||
|
||||
|
@ -70,7 +83,7 @@ pair @scheme[p].}
|
|||
|
||||
@defproc[(list? [v any/c]) boolean?]{Returns @scheme[#t] if @scheme[v]
|
||||
is a list: either the empty list, or a pair whose second element is a
|
||||
list.}
|
||||
list. This procedure takes amortized constant time.}
|
||||
|
||||
@defproc[(list [v any/c] ...) list?]{Returns a newly allocated list
|
||||
containing the @scheme[v]s as its elements.}
|
||||
|
@ -95,35 +108,6 @@ is the value produced by @scheme[(proc _i)].
|
|||
(build-list 5 (lambda (x) (* x x)))
|
||||
]}
|
||||
|
||||
@; ----------------------------------------
|
||||
@section{Mutable Pair Operations}
|
||||
|
||||
@defproc[(mpair? [v any/c]) boolean?]{Returns @scheme[#t] if @scheme[v] is
|
||||
a mutable pair, @scheme[#f] otherwise.}
|
||||
|
||||
@defproc[(mcons [a any/c] [d any/c]) pair?]{Returns a mutable pair whose first
|
||||
element is @scheme[a] and second element is @scheme[d].}
|
||||
|
||||
@defproc[(mcar [p mpair?]) any/c]{Returns the first element of the
|
||||
mutable pair @scheme[p].}
|
||||
|
||||
@defproc[(mcdr [p mpair?]) any/c]{Returns the second element of the
|
||||
mutable pair @scheme[p].}
|
||||
|
||||
|
||||
@defproc[(set-mcar! [p mpair?] [v any/v])
|
||||
void?]{
|
||||
|
||||
Changes the mutable pair @scheme[p] so that its first element is
|
||||
@scheme[v].}
|
||||
|
||||
@defproc[(set-mcdr! [p mpair?] [v any/v])
|
||||
void?]{
|
||||
|
||||
Changes the mutable pair @scheme[p] so that its second element is
|
||||
@scheme[v].}
|
||||
|
||||
|
||||
@; ----------------------------------------
|
||||
@section{List Operations}
|
||||
|
||||
|
@ -136,7 +120,7 @@ Returns the number of elements in @scheme[lst].}
|
|||
@defproc[(list-ref [lst list?][pos nonnegative-exact-integer?])
|
||||
any/c]{
|
||||
|
||||
Returns the element of @scheme[vec] at position @scheme[pos], where
|
||||
Returns the element of @scheme[lst] at position @scheme[pos], where
|
||||
the list's first element is position @scheme[0]. If the list has
|
||||
@scheme[pos] or fewer elements, then the
|
||||
@exnraise[exn:fail:contract].}
|
||||
|
|
|
@ -1589,7 +1589,7 @@ its variants export only definitions accessible from the lexical
|
|||
context of the @scheme[phaseless-spec] form.}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Interaction Wrapper: @scheme[#%top-interaction]}
|
||||
@section[#:tag "#%top-interaction"]{Interaction Wrapper: @scheme[#%top-interaction]}
|
||||
|
||||
@defform[(#%top-interaction . form)]{
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user