add examples for -> contract combinator

closes #2527

Thanks to Paulo Matos
This commit is contained in:
Robby Findler 2019-03-12 09:14:58 -05:00
parent 7ce28e8795
commit b8b0260e50

View File

@ -7,7 +7,7 @@
@(define contract-eval @(define contract-eval
(lambda () (lambda ()
(let ([the-eval (make-base-eval)]) (let ([the-eval (make-base-eval)])
(the-eval '(require racket/contract racket/contract/parametric racket/list)) (the-eval '(require racket/contract racket/contract/parametric racket/list racket/math))
the-eval))) the-eval)))
@(define blame-object @tech{blame object}) @(define blame-object @tech{blame object})
@ -1175,13 +1175,29 @@ produces a contract on functions of two arguments. The first argument
must be an integer, and the second argument must be a boolean. The must be an integer, and the second argument must be a boolean. The
function must produce an integer. function must produce an integer.
@examples[#:eval (contract-eval) #:once
(define/contract (maybe-invert i b)
(-> integer? boolean? integer?)
(if b (- i) i))
(maybe-invert 1 #t)
(eval:error (maybe-invert #f 1))]
A domain specification may include a keyword. If so, the function must A domain specification may include a keyword. If so, the function must
accept corresponding (mandatory) keyword arguments, and the values for accept corresponding (mandatory) keyword arguments, and the values for
the keyword arguments must match the corresponding contracts. For the keyword arguments must match the corresponding contracts. For
example: example:
@racketblock[(integer? #:x boolean? . -> . integer?)] @racketblock[(integer? #:invert? boolean? . -> . integer?)]
is a contract on a function that accepts a by-position argument that is a contract on a function that accepts a by-position argument that
is an integer and a @racket[#:x] argument that is a boolean. is an integer and an @racket[#:invert] argument that is a boolean.
@examples[#:eval (contract-eval) #:once
(define/contract (maybe-invert i #:invert? b)
(-> integer? #:invert? boolean? integer?)
(if b (- i) i))
(maybe-invert 1 #:invert? #t)
(eval:error (maybe-invert 1 #f))]
As an example that uses an @racket[...], this contract: As an example that uses an @racket[...], this contract:
@racketblock[(integer? string? ... integer? . -> . any)] @racketblock[(integer? string? ... integer? . -> . any)]
@ -1189,15 +1205,53 @@ on a function insists that the first and last arguments to
the function must be integers (and there must be at least the function must be integers (and there must be at least
two arguments) and any other arguments must be strings. two arguments) and any other arguments must be strings.
@examples[#:eval (contract-eval) #:once
(define/contract (string-length/between? lower-bound s1 . more-args)
(-> integer? string? ... integer? boolean?)
(define all-but-first-arg-backwards (reverse (cons s1 more-args)))
(define upper-bound (first all-but-first-arg-backwards))
(define strings (rest all-but-first-arg-backwards))
(define strings-length
(for/sum ([str (in-list strings)])
(string-length str)))
(<= lower-bound strings-length upper-bound))
(string-length/between? 4 "farmer" "john" 40)
(eval:error (string-length/between? 4 "farmer" 'john 40))
(eval:error (string-length/between? 4 "farmer" "john" "fourty"))]
If @racket[any] is used as the last sub-form for @racket[->], no If @racket[any] is used as the last sub-form for @racket[->], no
contract checking is performed on the result of the function, and contract checking is performed on the result of the function, and
thus any number of values is legal (even different numbers on different thus any number of values is legal (even different numbers on different
invocations of the function). invocations of the function).
@examples[#:eval (contract-eval) #:once
(define/contract (multiple-xs n x)
(-> natural? any/c any)
(apply
values
(for/list ([_ (in-range n)])
n)))
(multiple-xs 4 "four")]
If @racket[(values range-expr ...)] is used as the last sub-form of If @racket[(values range-expr ...)] is used as the last sub-form of
@racket[->], the function must produce a result for each contract, and @racket[->], the function must produce a result for each contract, and
each value must match its respective contract. each value must match its respective contract.
@examples[#:eval (contract-eval) #:once
(define/contract (multiple-xs n x)
(-> natural? any/c (values any/c any/c any/c))
(apply
values
(for/list ([_ (in-range n)])
n)))
(multiple-xs 3 "three")
(eval:error (multiple-xs 4 "four"))]
@history[#:changed "6.4.0.5" @list{Added support for ellipses}] @history[#:changed "6.4.0.5" @list{Added support for ellipses}]
} }