www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

split-xlist.scrbl (4132B)


      1 #lang scribble/manual
      2 @require[phc-toolkit/scribblings/utils
      3          scribble/examples
      4          @for-label[xlist
      5                     typed/racket/base]]
      6 
      7 @title{Splitting an xlist in its constituent sublists}
      8 @(declare-exporting xlist)
      9 
     10 @(define make-eval (make-eval-factory '(xlist type-expander)
     11                                       #:lang 'typed/racket))
     12 
     13 @defform*[#:kind "match-expander"
     14           #:literals (^ * + - ∞)
     15           [(split-xlist pat τᵢ ...)
     16            (split-xlist pat τᵢ ... . rest)
     17            (split-xlist pat τᵢ ... #:rest rest)]
     18           #:grammar
     19           [(τᵢ type
     20                repeated-type)
     21            (repeated-type (code:line type ^ repeat)
     22                           (code:line type ^ {repeat})
     23                           (code:line type {repeat})
     24                           (code:line type superscripted-repeat)
     25                           (code:line type *)
     26                           (code:line type +)
     27                           (code:line superscripted-id))
     28            (repeat (code:line once)
     29                    (code:line nat)
     30                    (code:line nat +)
     31                    (code:line +)
     32                    (code:line nat - nat)
     33                    (code:line nat - ∞)
     34                    (code:line nat -)
     35                    (code:line - nat)
     36                    (code:line -)
     37                    (code:line - ∞)
     38                    (code:line *))]
     39           #:contracts
     40           [(nat (syntax/c exact-nonnegative-integer?))]]{
     41  This match pattern splits an xlist into a list of lists, and matches the
     42  result against @racket[pat]. Each repeated element of the xlist is extracted
     43  into one of these sublists. The type for each sublist is determined based on
     44  the element's type and its @racket[_repeat]:
     45  @itemlist[
     46  @item{If the @racket[_repeat] for that element is @racket[once], then the
     47    element is inserted directly, without nesting it within a sublist. In
     48    contrast, it the @racket[_repeat] were @racket[1], the element would be
     49    inserted in a sublist of length one.}
     50  @item{If the @racket[_repeat] for that element is @racket[*] or an
     51    equivalent, the type of the sublist will be @racket[(Listof type)]}
     52  @item{If the @racket[_repeat] for that element is @racket[_n +] or an
     53    equivalent, the type of the sublist will be @racket[(xList type ^ _n +)]}
     54  @item{If the @racket[_repeat] for that element is @racket[_n] or an
     55    equivalent, the type of the sublist will be @racket[(xList type ^ _n)]}
     56  @item{If the @racket[_repeat] for that element is @racket[_from - _to] or an
     57    equivalent, the type of the sublist will be
     58    @racket[(xList type ^ _from - _to)]}
     59  @item{The @racket[#:rest] or dotted rest is included as the last element of
     60    the list matched against @racket[pat]. If the first form without a rest type
     61    is used, the list matched against @racket[pat] still contains @racket['()] as
     62    a last element:
     63    @examples[#:eval (make-eval)
     64              (match '(1 2 3)
     65                [(split-xlist (list (list a) (list b c) (? null?))
     66                              Number¹ Number⃰)
     67                 (vector c b a)])]}]
     68 
     69  Note that @racket[split-xlist] assumes the value it is matched against has
     70  the type @racket[(xlist τᵢ ... maybe-rest)], but does not apply
     71  @racket[(? (make-predicate (xlist τᵢ ... maybe-rest)))] to the value itself.
     72  The rationale is that the @racket[make-predicate] may fail at compile-time if
     73  it cannot generate a contract for the given type. In some cases, however
     74  @racket[split-xlist] will still manage to successfully generate the match
     75  pattern, and can be used on its own, provided that the value is statically
     76  known to be of the right type.
     77 
     78  It is therefore recommended to use @racket[split-xlist] as follows when the
     79  type of the value is not known to be acceptable by @racket[split-xlist]:
     80 
     81  @examples[#:eval (make-eval)
     82            (define v : Any '(1 2 3))
     83            (match '(1 2 3)
     84              [(and (? (make-predicate (xlist Number¹ Number⃰)))
     85                    (split-xlist (list (list a) (list b c) (? null?))
     86                                 Number¹ Number⃰))
     87               'success])]}