racket/collects/unstable/scribblings/find.scrbl
2009-11-19 08:29:57 +00:00

78 lines
2.8 KiB
Racket

#lang scribble/manual
@(require scribble/eval
"utils.ss"
(for-label unstable/find
scheme/contract
scheme/shared
scheme/base))
@title[#:tag "find"]{Find}
@(define the-eval (make-base-eval))
@(the-eval '(require unstable/find))
@(the-eval '(require scheme/shared))
@defmodule[unstable/find]
@unstable[@author+email["Ryan Culpepper" "ryanc@plt-scheme.org"]]
@defproc[(find [pred (-> any/c any/c)]
[x any/c]
[#:stop-on-found? stop-on-found? any/c #f]
[#:stop stop (or/c #f (-> any/c any/c)) #f]
[#:get-children get-children (or/c #f (-> any/c (or/c #f list?))) #f])
list?]{
Returns a list of all values satisfying @scheme[pred] contained in
@scheme[x] (possibly including @scheme[x] itself).
If @scheme[stop-on-found?] is true, the children of values satisfying
@scheme[pred] are not examined. If @scheme[stop] is a procedure, then
the children of values for which @scheme[stop] returns true are not
examined (but the values themselves are; @scheme[stop] is applied
after @scheme[pred]). Only the current branch of the search is
stopped, not the whole search.
The search recurs through pairs, vectors, boxes, and the accessible
fields of structures. If @scheme[get-children] is a procedure, it can
override the default notion of a value's children by returning a list
(if it returns false, the default notion of children is used).
No cycle detection is done, so @scheme[find] on a cyclic graph may
diverge. To do cycle checking yourself, use @scheme[stop] and a
mutable table.
@examples[#:eval the-eval
(find symbol? '((all work) and (no play)))
(find list? '#((all work) and (no play)) #:stop-on-found? #t)
(find negative? 100
#:stop-on-found? #t
#:get-children (lambda (n) (list (- n 12))))
(find symbol? (shared ([x (cons 'a x)]) x)
#:stop (let ([table (make-hasheq)])
(lambda (x)
(begin0 (hash-ref table x #f)
(hash-set! table x #t)))))
]
}
@defproc[(find-first [pred (-> any/c any/c)]
[x any/c]
[#:stop stop (or/c #f (-> any/c any/c)) #f]
[#:get-children get-children (or/c #f (-> any/c (or/c #f list?))) #f]
[#:default default any/c (lambda () (error ....))])
any/c]{
Like @scheme[find], but only returns the first match. If no
matches are found, @scheme[default] is applied as a thunk if it is a
procedure or returned otherwise.
@examples[#:eval the-eval
(find-first symbol? '((all work) and (no play)))
(find-first list? '#((all work) and (no play)))
(find-first negative? 100
#:get-children (lambda (n) (list (- n 12))))
(find-first symbol? (shared ([x (cons 'a x)]) x))
]
}