added list-contract?
and specialized a bunch of list-related contracts to track list?-ness, notably recursive-contract now accepts a #:list-contract? argument that means that it insists that values it accepts be list? (and thus not cyclic) related to PR 14559
This commit is contained in:
parent
0db4df1d33
commit
f49dd363fa
|
@ -187,6 +187,9 @@ For example, this contract
|
||||||
does not accept a function like this one: @racket[(lambda args ...)]
|
does not accept a function like this one: @racket[(lambda args ...)]
|
||||||
since it cannot tell which of the two arrow contracts should be used
|
since it cannot tell which of the two arrow contracts should be used
|
||||||
with the function.
|
with the function.
|
||||||
|
|
||||||
|
If all of its arguments are @racket[list-contract?]s, then @racket[or/c]
|
||||||
|
returns a @racket[list-contract?].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(and/c [contract contract?] ...) contract?]{
|
@defproc[(and/c [contract contract?] ...) contract?]{
|
||||||
|
@ -369,14 +372,14 @@ Returns the same contract as @racket[(box/c c #:immutable #t)]. This form exists
|
||||||
reasons of backwards compatibility.}
|
reasons of backwards compatibility.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(listof [c contract?]) contract?]{
|
@defproc[(listof [c contract?]) list-contract?]{
|
||||||
|
|
||||||
Returns a contract that recognizes a list whose every element matches
|
Returns a contract that recognizes a list whose every element matches
|
||||||
the contract @racket[c]. Beware that when this contract is applied to
|
the contract @racket[c]. Beware that when this contract is applied to
|
||||||
a value, the result is not necessarily @racket[eq?] to the input.}
|
a value, the result is not necessarily @racket[eq?] to the input.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(non-empty-listof [c contract?]) contract?]{
|
@defproc[(non-empty-listof [c contract?]) list-contract?]{
|
||||||
|
|
||||||
Returns a contract that recognizes non-empty lists whose elements match
|
Returns a contract that recognizes non-empty lists whose elements match
|
||||||
the contract @racket[c]. Beware that when this contract is applied to
|
the contract @racket[c]. Beware that when this contract is applied to
|
||||||
|
@ -387,10 +390,16 @@ a value, the result is not necessarily @racket[eq?] to the input.}
|
||||||
Produces a contract that recognizes pairs whose first and second elements
|
Produces a contract that recognizes pairs whose first and second elements
|
||||||
match @racket[car-c] and @racket[cdr-c], respectively. Beware that
|
match @racket[car-c] and @racket[cdr-c], respectively. Beware that
|
||||||
when this contract is applied to a value, the result is not
|
when this contract is applied to a value, the result is not
|
||||||
necessarily @racket[eq?] to the input.}
|
necessarily @racket[eq?] to the input.
|
||||||
|
|
||||||
|
If the @racket[cdr-c] contract is a @racket[list-contract?], then
|
||||||
|
@racket[cons/c] returns a @racket[list-contract?].
|
||||||
|
|
||||||
|
@history[#:changed "6.0.1.13" @list{Added the @racket[list-contract?] propagating behavior.}]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(list/c [c contract?] ...) contract?]{
|
@defproc[(list/c [c contract?] ...) list-contract?]{
|
||||||
|
|
||||||
Produces a contract for a list. The number of elements in the list
|
Produces a contract for a list. The number of elements in the list
|
||||||
must match the number of arguments supplied to @racket[list/c], and
|
must match the number of arguments supplied to @racket[list/c], and
|
||||||
|
@ -1858,7 +1867,8 @@ the contract library primitives below.
|
||||||
name x))))]
|
name x))))]
|
||||||
[#:stronger stronger
|
[#:stronger stronger
|
||||||
(or/c #f (-> contract? contract? boolean?))
|
(or/c #f (-> contract? contract? boolean?))
|
||||||
#f])
|
#f]
|
||||||
|
[#:list-contract is-list-contract? boolean? #f])
|
||||||
contract?]
|
contract?]
|
||||||
@defproc[(make-chaperone-contract
|
@defproc[(make-chaperone-contract
|
||||||
[#:name name any/c 'anonymous-chaperone-contract]
|
[#:name name any/c 'anonymous-chaperone-contract]
|
||||||
|
@ -1878,7 +1888,8 @@ the contract library primitives below.
|
||||||
name x))))]
|
name x))))]
|
||||||
[#:stronger stronger
|
[#:stronger stronger
|
||||||
(or/c #f (-> contract? contract? boolean?))
|
(or/c #f (-> contract? contract? boolean?))
|
||||||
#f])
|
#f]
|
||||||
|
[#:list-contract is-list-contract? boolean? #f])
|
||||||
chaperone-contract?]
|
chaperone-contract?]
|
||||||
@defproc[(make-flat-contract
|
@defproc[(make-flat-contract
|
||||||
[#:name name any/c 'anonymous-flat-contract]
|
[#:name name any/c 'anonymous-flat-contract]
|
||||||
|
@ -1898,7 +1909,8 @@ the contract library primitives below.
|
||||||
name x))))]
|
name x))))]
|
||||||
[#:stronger stronger
|
[#:stronger stronger
|
||||||
(or/c #f (-> contract? contract? boolean?))
|
(or/c #f (-> contract? contract? boolean?))
|
||||||
#f])
|
#f]
|
||||||
|
[#:list-contract is-list-contract? boolean? #f])
|
||||||
flat-contract?]
|
flat-contract?]
|
||||||
)]{
|
)]{
|
||||||
|
|
||||||
|
@ -1946,6 +1958,9 @@ The @racket[stronger] argument is used to implement @racket[contract-stronger?].
|
||||||
first argument is always the contract itself and the second argument is whatever
|
first argument is always the contract itself and the second argument is whatever
|
||||||
was passed as the second argument to @racket[contract-stronger?].
|
was passed as the second argument to @racket[contract-stronger?].
|
||||||
|
|
||||||
|
The @racket[is-list-contract?] argument is used by the @racket[list-contract?] predicate
|
||||||
|
to determine if this is a contract that accepts only @racket[list?] values.
|
||||||
|
|
||||||
@defexamples[#:eval (contract-eval)
|
@defexamples[#:eval (contract-eval)
|
||||||
(define int/c
|
(define int/c
|
||||||
(make-flat-contract #:name 'int/c #:first-order integer?))
|
(make-flat-contract #:name 'int/c #:first-order integer?))
|
||||||
|
@ -1977,6 +1992,7 @@ was passed as the second argument to @racket[contract-stronger?].
|
||||||
(halve 1)
|
(halve 1)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@history[#:changed "6.0.1.13" @list{Added the @racket[#:list-contract?] argument.}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(build-compound-type-name [c/s any/c] ...) any]{
|
@defproc[(build-compound-type-name [c/s any/c] ...) any]{
|
||||||
|
@ -2306,7 +2322,8 @@ is expected to be the blame record for the contract on the value).
|
||||||
(-> (and/c positive? real?)
|
(-> (and/c positive? real?)
|
||||||
(values
|
(values
|
||||||
(-> c void?)
|
(-> c void?)
|
||||||
(listof contract?)))]))])
|
(listof contract?)))]))]
|
||||||
|
[#:list-contract? is-list-contract? (-> contract? boolean?) (λ (c) #f)])
|
||||||
flat-contract-property?]
|
flat-contract-property?]
|
||||||
@defproc[(build-chaperone-contract-property
|
@defproc[(build-chaperone-contract-property
|
||||||
[#:name
|
[#:name
|
||||||
|
@ -2353,7 +2370,8 @@ is expected to be the blame record for the contract on the value).
|
||||||
(-> (and/c positive? real?)
|
(-> (and/c positive? real?)
|
||||||
(values
|
(values
|
||||||
(-> c void?)
|
(-> c void?)
|
||||||
(listof contract?)))]))])
|
(listof contract?)))]))]
|
||||||
|
[#:list-contract? is-list-contract? (-> contract? boolean?) (λ (c) #f)])
|
||||||
chaperone-contract-property?]
|
chaperone-contract-property?]
|
||||||
@defproc[(build-contract-property
|
@defproc[(build-contract-property
|
||||||
[#:name
|
[#:name
|
||||||
|
@ -2400,7 +2418,8 @@ is expected to be the blame record for the contract on the value).
|
||||||
(-> (and/c positive? real?)
|
(-> (and/c positive? real?)
|
||||||
(values
|
(values
|
||||||
(-> c void?)
|
(-> c void?)
|
||||||
(listof contract?)))]))])
|
(listof contract?)))]))]
|
||||||
|
[#:list-contract? is-list-contract? (-> contract? boolean?) (λ (c) #f)])
|
||||||
contract-property?])]{
|
contract-property?])]{
|
||||||
|
|
||||||
@italic{The precise details of the
|
@italic{The precise details of the
|
||||||
|
@ -2423,10 +2442,12 @@ produces a blame-tracking projection defining the behavior of the contract;
|
||||||
(passed in the first argument) is stronger than some other contract (passed
|
(passed in the first argument) is stronger than some other contract (passed
|
||||||
in the second argument); @racket[generate], which returns a thunk
|
in the second argument); @racket[generate], which returns a thunk
|
||||||
that generates random values matching the contract or @racket[#f], indicating
|
that generates random values matching the contract or @racket[#f], indicating
|
||||||
that random generation for this contract isn't supported; and @racket[exercise],
|
that random generation for this contract isn't supported; @racket[exercise],
|
||||||
which returns a function that exercises values matching the contract (e.g.,
|
which returns a function that exercises values matching the contract (e.g.,
|
||||||
if it is a function contract, it may call the function) and a list of contracts
|
if it is a function contract, it may call the function) and a list of contracts
|
||||||
whose values will be generated by this process.
|
whose values will be generated by this process; and @racket[is-flat-contract?],
|
||||||
|
which is used by @racket[flat-contract?] to determine if this contract
|
||||||
|
accepts only @racket[list?]s.
|
||||||
|
|
||||||
These accessors are passed as (optional) keyword arguments to
|
These accessors are passed as (optional) keyword arguments to
|
||||||
@racket[build-contract-property], and are applied to instances of the
|
@racket[build-contract-property], and are applied to instances of the
|
||||||
|
@ -2448,6 +2469,7 @@ projection accessor is expected not to wrap its argument in a higher-order
|
||||||
fashion, analogous to the constraint on projections in
|
fashion, analogous to the constraint on projections in
|
||||||
@racket[make-flat-contract].
|
@racket[make-flat-contract].
|
||||||
|
|
||||||
|
@history[#:changed "6.0.1.13" @list{Added the @racket[#:list-contract?] argument.}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@deftogether[(
|
@deftogether[(
|
||||||
|
@ -2628,6 +2650,17 @@ symbols, booleans, numbers, and other ordinary Racket values
|
||||||
(that are defined as @tech{contracts}) are also
|
(that are defined as @tech{contracts}) are also
|
||||||
flat contracts.}
|
flat contracts.}
|
||||||
|
|
||||||
|
@defproc[(list-contract? [v any/c]) boolean?]{
|
||||||
|
Recognizes certain @racket[contract?] values that accept @racket[list?]s.
|
||||||
|
|
||||||
|
A list contract is one that insists that its argument
|
||||||
|
is a @racket[list?], meaning that the value cannot be cyclic
|
||||||
|
and must either be the empty list or a pair constructed
|
||||||
|
with @racket[cons] and another list.
|
||||||
|
|
||||||
|
@history[#:added "6.0.1.13"]
|
||||||
|
}
|
||||||
|
|
||||||
@defproc[(contract-name [c contract?]) any/c]{
|
@defproc[(contract-name [c contract?]) any/c]{
|
||||||
Produces the name used to describe the contract in error messages.
|
Produces the name used to describe the contract in error messages.
|
||||||
}
|
}
|
||||||
|
@ -2670,13 +2703,22 @@ Makes a contract that accepts no values, and reports the
|
||||||
name @racket[sexp-name] when signaling a contract violation.}
|
name @racket[sexp-name] when signaling a contract violation.}
|
||||||
|
|
||||||
@defform*[[(recursive-contract contract-expr)
|
@defform*[[(recursive-contract contract-expr)
|
||||||
(recursive-contract contract-expr type)]]{
|
(recursive-contract contract-expr #:list-contract?)
|
||||||
|
(recursive-contract contract-expr type)
|
||||||
|
(recursive-contract contract-expr type #:list-contract?)]]{
|
||||||
|
|
||||||
Delays the evaluation of its argument until the contract is checked,
|
Delays the evaluation of its argument until the contract is checked,
|
||||||
making recursive contracts possible. If @racket[type] is given, it
|
making recursive contracts possible. If @racket[type] is given, it
|
||||||
describes the expected type of contract and must be one of the keywords
|
describes the expected type of contract and must be one of the keywords
|
||||||
@racket[#:impersonator], @racket[#:chaperone], or @racket[#:flat]. If
|
@racket[#:impersonator], @racket[#:chaperone], or @racket[#:flat]. If
|
||||||
@racket[type] is not given, an impersonator contract is created.}
|
@racket[type] is not given, an impersonator contract is created.
|
||||||
|
|
||||||
|
If @racket[#:list-contract?] is returned, then the result is a
|
||||||
|
@racket[list-contract?] and the @racket[contract-expr] must evaluate
|
||||||
|
to a @racket[list-contract?].
|
||||||
|
|
||||||
|
@history[#:changed "6.0.1.13" @list{Added the @racket[#:list-contract?] argument.}]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@defform/subs[(opt/c contract-expr maybe-name)
|
@defform/subs[(opt/c contract-expr maybe-name)
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
#lang racket/base
|
||||||
|
(require "test-util.rkt")
|
||||||
|
(parameterize ([current-contract-namespace (make-basic-contract-namespace 'racket/list)])
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-1
|
||||||
|
'(list-contract? 1)
|
||||||
|
#f)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-2
|
||||||
|
'(list-contract? (λ (a b c) a)) ;; somethign that's not coerceable to a contract
|
||||||
|
#f)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-3
|
||||||
|
'(list-contract? '())
|
||||||
|
#t)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-4
|
||||||
|
'(list-contract? null?)
|
||||||
|
#t)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-5
|
||||||
|
'(list-contract? empty?)
|
||||||
|
#t)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-6
|
||||||
|
'(list-contract? boolean?)
|
||||||
|
#f)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-7
|
||||||
|
'(list-contract? any/c)
|
||||||
|
#f)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-8
|
||||||
|
'(list-contract? (cons/c 1 empty?))
|
||||||
|
#t)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-9
|
||||||
|
'(list-contract? (cons/c 1 2))
|
||||||
|
#f)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-10
|
||||||
|
'(list-contract? (listof any/c))
|
||||||
|
#t)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-11
|
||||||
|
'(list-contract? (non-empty-listof any/c))
|
||||||
|
#t)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-12
|
||||||
|
'(list-contract? (list/c 1 2 3))
|
||||||
|
#t)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-13
|
||||||
|
'(list-contract? (or/c (cons/c 1 empty?) empty?))
|
||||||
|
#t)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-14
|
||||||
|
'(list-contract? (or/c (cons/c (-> integer? integer?) empty?)
|
||||||
|
empty?))
|
||||||
|
#t)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-15
|
||||||
|
'(list-contract? (or/c (cons/c (-> integer? integer?) empty?)
|
||||||
|
(cons/c (-> integer? integer? integer?) empty?)
|
||||||
|
empty?))
|
||||||
|
#t)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-16
|
||||||
|
'(list-contract?
|
||||||
|
(letrec ([c (recursive-contract (or/c (cons/c 1 c) empty?))])
|
||||||
|
c))
|
||||||
|
#f)
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'list-contract-17
|
||||||
|
'(list-contract?
|
||||||
|
(letrec ([c (recursive-contract (or/c (cons/c 1 c) empty?) #:list-contract?)])
|
||||||
|
c))
|
||||||
|
#t)
|
||||||
|
|
||||||
|
(test/pos-blame
|
||||||
|
'test-contract-18
|
||||||
|
'(contract (letrec ([c (recursive-contract (or/c (cons/c any/c c) empty?)
|
||||||
|
#:list-contract?)])
|
||||||
|
c)
|
||||||
|
(read (open-input-string "#1=(1 . #1#)"))
|
||||||
|
'pos 'neg))
|
||||||
|
|
||||||
|
|
||||||
|
(contract-error-test
|
||||||
|
'test-contract-19
|
||||||
|
'(contract (recursive-contract 1 #:list-contract?)
|
||||||
|
1
|
||||||
|
'pos 'neg)
|
||||||
|
(λ (x)
|
||||||
|
(and (exn:fail? x)
|
||||||
|
(regexp-match #rx"list-contract[?]" (exn-message x))))))
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
has-blame?
|
has-blame?
|
||||||
value-blame
|
value-blame
|
||||||
contract-continuation-mark-key
|
contract-continuation-mark-key
|
||||||
|
list-contract?
|
||||||
|
|
||||||
;; from private/case-arrow.rkt
|
;; from private/case-arrow.rkt
|
||||||
case->)
|
case->)
|
||||||
|
|
|
@ -103,7 +103,7 @@
|
||||||
'#,(build-source-location-vector #'ctc))))]))
|
'#,(build-source-location-vector #'ctc))))]))
|
||||||
|
|
||||||
(define-syntax (-recursive-contract stx)
|
(define-syntax (-recursive-contract stx)
|
||||||
(define (do-recursive-contract arg type name)
|
(define (do-recursive-contract arg type name list-contract?)
|
||||||
(define local-name (syntax-local-infer-name stx))
|
(define local-name (syntax-local-infer-name stx))
|
||||||
(define maker
|
(define maker
|
||||||
(case (syntax-e type)
|
(case (syntax-e type)
|
||||||
|
@ -115,13 +115,18 @@
|
||||||
"type must be one of #:impersonator, #:chaperone, or #:flat"
|
"type must be one of #:impersonator, #:chaperone, or #:flat"
|
||||||
stx
|
stx
|
||||||
type)]))
|
type)]))
|
||||||
#`(#,maker '#,name (λ () #,arg) '#,local-name))
|
#`(#,maker '#,name (λ () #,arg) '#,local-name #,list-contract?))
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
|
[(_ arg type #:list-contract?)
|
||||||
|
(keyword? (syntax-e #'type))
|
||||||
|
(do-recursive-contract #'arg #'type #'(recursive-contract arg type) #t)]
|
||||||
|
[(_ arg #:list-contract?)
|
||||||
|
(do-recursive-contract #'arg #'#:impersonator #'(recursive-contract arg) #t)]
|
||||||
[(_ arg type)
|
[(_ arg type)
|
||||||
(keyword? (syntax-e #'type))
|
(keyword? (syntax-e #'type))
|
||||||
(do-recursive-contract #'arg #'type #'(recursive-contract arg type))]
|
(do-recursive-contract #'arg #'type #'(recursive-contract arg type) #f)]
|
||||||
[(_ arg)
|
[(_ arg)
|
||||||
(do-recursive-contract #'arg #'#:impersonator #'(recursive-contract arg))]))
|
(do-recursive-contract #'arg #'#:impersonator #'(recursive-contract arg) #f)]))
|
||||||
|
|
||||||
(define (force-recursive-contract ctc)
|
(define (force-recursive-contract ctc)
|
||||||
(define current (recursive-contract-ctc ctc))
|
(define current (recursive-contract-ctc ctc))
|
||||||
|
@ -138,19 +143,37 @@
|
||||||
(coerce-chaperone-contract 'recursive-contract (thunk))]
|
(coerce-chaperone-contract 'recursive-contract (thunk))]
|
||||||
[(impersonator-recursive-contract? ctc)
|
[(impersonator-recursive-contract? ctc)
|
||||||
(coerce-contract 'recursive-contract (thunk))]))
|
(coerce-contract 'recursive-contract (thunk))]))
|
||||||
|
(when (recursive-contract-list-contract? ctc)
|
||||||
|
(unless (list-contract? forced-ctc)
|
||||||
|
(raise-argument-error 'recursive-contract "list-contract?" forced-ctc)))
|
||||||
(set-recursive-contract-ctc! ctc forced-ctc)
|
(set-recursive-contract-ctc! ctc forced-ctc)
|
||||||
(set-recursive-contract-name! ctc (append `(recursive-contract ,(contract-name forced-ctc))
|
(set-recursive-contract-name! ctc (append `(recursive-contract ,(contract-name forced-ctc))
|
||||||
(cddr old-name)))
|
(cddr old-name)))
|
||||||
forced-ctc]
|
forced-ctc]
|
||||||
[else current]))
|
[else current]))
|
||||||
|
|
||||||
(define ((recursive-contract-projection ctc) blame)
|
(define (recursive-contract-projection ctc)
|
||||||
(define r-ctc (force-recursive-contract ctc))
|
(cond
|
||||||
(define f (contract-projection r-ctc))
|
[(recursive-contract-list-contract? ctc)
|
||||||
(define blame-known (blame-add-context blame #f))
|
(λ (blame)
|
||||||
(λ (val)
|
(define r-ctc (force-recursive-contract ctc))
|
||||||
((f blame-known) val)))
|
(define f (contract-projection r-ctc))
|
||||||
|
(define blame-known (blame-add-context blame #f))
|
||||||
|
(λ (val)
|
||||||
|
(unless (list? val)
|
||||||
|
(raise-blame-error blame-known
|
||||||
|
val
|
||||||
|
'(expected: "list?" given: "~e")
|
||||||
|
val))
|
||||||
|
((f blame-known) val)))]
|
||||||
|
[else
|
||||||
|
(λ (blame)
|
||||||
|
(define r-ctc (force-recursive-contract ctc))
|
||||||
|
(define f (contract-projection r-ctc))
|
||||||
|
(define blame-known (blame-add-context blame #f))
|
||||||
|
(λ (val)
|
||||||
|
((f blame-known) val)))]))
|
||||||
|
|
||||||
(define (recursive-contract-stronger this that)
|
(define (recursive-contract-stronger this that)
|
||||||
(and (recursive-contract? that)
|
(and (recursive-contract? that)
|
||||||
(procedure-closure-contents-eq? (recursive-contract-thunk this)
|
(procedure-closure-contents-eq? (recursive-contract-thunk this)
|
||||||
|
@ -160,7 +183,7 @@
|
||||||
(contract-first-order-passes? (force-recursive-contract ctc)
|
(contract-first-order-passes? (force-recursive-contract ctc)
|
||||||
val))
|
val))
|
||||||
|
|
||||||
(struct recursive-contract ([name #:mutable] thunk [ctc #:mutable]))
|
(struct recursive-contract ([name #:mutable] thunk [ctc #:mutable] list-contract?))
|
||||||
|
|
||||||
(struct flat-recursive-contract recursive-contract ()
|
(struct flat-recursive-contract recursive-contract ()
|
||||||
#:property prop:custom-write custom-write-property-proc
|
#:property prop:custom-write custom-write-property-proc
|
||||||
|
@ -169,7 +192,8 @@
|
||||||
#:name recursive-contract-name
|
#:name recursive-contract-name
|
||||||
#:first-order recursive-contract-first-order
|
#:first-order recursive-contract-first-order
|
||||||
#:projection recursive-contract-projection
|
#:projection recursive-contract-projection
|
||||||
#:stronger recursive-contract-stronger))
|
#:stronger recursive-contract-stronger
|
||||||
|
#:list-contract? recursive-contract-list-contract?))
|
||||||
(struct chaperone-recursive-contract recursive-contract ()
|
(struct chaperone-recursive-contract recursive-contract ()
|
||||||
#:property prop:custom-write custom-write-property-proc
|
#:property prop:custom-write custom-write-property-proc
|
||||||
#:property prop:chaperone-contract
|
#:property prop:chaperone-contract
|
||||||
|
@ -177,7 +201,8 @@
|
||||||
#:name recursive-contract-name
|
#:name recursive-contract-name
|
||||||
#:first-order recursive-contract-first-order
|
#:first-order recursive-contract-first-order
|
||||||
#:projection recursive-contract-projection
|
#:projection recursive-contract-projection
|
||||||
#:stronger recursive-contract-stronger))
|
#:stronger recursive-contract-stronger
|
||||||
|
#:list-contract? recursive-contract-list-contract?))
|
||||||
(struct impersonator-recursive-contract recursive-contract ()
|
(struct impersonator-recursive-contract recursive-contract ()
|
||||||
#:property prop:custom-write custom-write-property-proc
|
#:property prop:custom-write custom-write-property-proc
|
||||||
#:property prop:contract
|
#:property prop:contract
|
||||||
|
@ -185,4 +210,5 @@
|
||||||
#:name recursive-contract-name
|
#:name recursive-contract-name
|
||||||
#:first-order recursive-contract-first-order
|
#:first-order recursive-contract-first-order
|
||||||
#:projection recursive-contract-projection
|
#:projection recursive-contract-projection
|
||||||
#:stronger recursive-contract-stronger))
|
#:stronger recursive-contract-stronger
|
||||||
|
#:list-contract? recursive-contract-list-contract?))
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"rand.rkt"
|
"rand.rkt"
|
||||||
"generate-base.rkt"
|
"generate-base.rkt"
|
||||||
racket/pretty
|
racket/pretty
|
||||||
|
racket/list
|
||||||
(for-syntax racket/base
|
(for-syntax racket/base
|
||||||
"helpers.rkt"))
|
"helpers.rkt"))
|
||||||
|
|
||||||
|
@ -20,7 +21,8 @@
|
||||||
build-compound-type-name
|
build-compound-type-name
|
||||||
|
|
||||||
contract-stronger?
|
contract-stronger?
|
||||||
|
list-contract?
|
||||||
|
|
||||||
contract-first-order
|
contract-first-order
|
||||||
contract-first-order-passes?
|
contract-first-order-passes?
|
||||||
|
|
||||||
|
@ -123,6 +125,10 @@
|
||||||
(coerce-contract 'contract-first-order-passes? c))
|
(coerce-contract 'contract-first-order-passes? c))
|
||||||
v))
|
v))
|
||||||
|
|
||||||
|
(define (list-contract? raw-c)
|
||||||
|
(define c (coerce-contract/f raw-c))
|
||||||
|
(and c (contract-struct-list-contract? c)))
|
||||||
|
|
||||||
;; contract-stronger? : contract contract -> boolean
|
;; contract-stronger? : contract contract -> boolean
|
||||||
;; indicates if one contract is stronger (ie, likes fewer values) than another
|
;; indicates if one contract is stronger (ie, likes fewer values) than another
|
||||||
;; this is not a total order.
|
;; this is not a total order.
|
||||||
|
@ -207,6 +213,7 @@
|
||||||
x
|
x
|
||||||
#f
|
#f
|
||||||
(memq x the-known-good-contracts))]
|
(memq x the-known-good-contracts))]
|
||||||
|
[(null? x) (make-eq-contract x)]
|
||||||
[(or (symbol? x) (boolean? x) (char? x) (null? x) (keyword? x)) (make-eq-contract x)]
|
[(or (symbol? x) (boolean? x) (char? x) (null? x) (keyword? x)) (make-eq-contract x)]
|
||||||
[(or (bytes? x) (string? x)) (make-equal-contract x)]
|
[(or (bytes? x) (string? x)) (make-equal-contract x)]
|
||||||
[(number? x) (make-=-contract x)]
|
[(number? x) (make-=-contract x)]
|
||||||
|
@ -356,7 +363,8 @@
|
||||||
(eq? this-val (eq-contract-val that)))
|
(eq? this-val (eq-contract-val that)))
|
||||||
(and (predicate-contract? that)
|
(and (predicate-contract? that)
|
||||||
(predicate-contract-sane? that)
|
(predicate-contract-sane? that)
|
||||||
((predicate-contract-pred that) this-val))))))
|
((predicate-contract-pred that) this-val))))
|
||||||
|
#:list-contract? (λ (c) (null? (eq-contract-val c)))))
|
||||||
|
|
||||||
(define-struct equal-contract (val)
|
(define-struct equal-contract (val)
|
||||||
#:property prop:custom-write custom-write-property-proc
|
#:property prop:custom-write custom-write-property-proc
|
||||||
|
@ -451,7 +459,9 @@
|
||||||
(predicate-contract-name ctc)))
|
(predicate-contract-name ctc)))
|
||||||
(λ (fuel)
|
(λ (fuel)
|
||||||
(and built-in-generator
|
(and built-in-generator
|
||||||
(λ () (built-in-generator fuel))))])))))
|
(λ () (built-in-generator fuel))))])))
|
||||||
|
#:list-contract? (λ (ctc) (or (equal? (predicate-contract-pred ctc) null?)
|
||||||
|
(equal? (predicate-contract-pred ctc) empty?)))))
|
||||||
|
|
||||||
(define (check-flat-named-contract predicate) (coerce-flat-contract 'flat-named-contract predicate))
|
(define (check-flat-named-contract predicate) (coerce-flat-contract 'flat-named-contract predicate))
|
||||||
(define (check-flat-contract predicate) (coerce-flat-contract 'flat-contract predicate))
|
(define (check-flat-contract predicate) (coerce-flat-contract 'flat-contract predicate))
|
||||||
|
|
|
@ -466,7 +466,8 @@
|
||||||
#:projection (listof-*-ho-check (λ (p v) (for-each p v) v))
|
#:projection (listof-*-ho-check (λ (p v) (for-each p v) v))
|
||||||
#:val-first-projection (listof-*-val-first-flat-proj predicate? ctc)
|
#:val-first-projection (listof-*-val-first-flat-proj predicate? ctc)
|
||||||
#:generate (generate ctc)
|
#:generate (generate ctc)
|
||||||
#:exercise (exercise ctc))]
|
#:exercise (exercise ctc)
|
||||||
|
#:list-contract? #t)]
|
||||||
[(chaperone-contract? ctc)
|
[(chaperone-contract? ctc)
|
||||||
(make-chaperone-contract
|
(make-chaperone-contract
|
||||||
#:name ctc-name
|
#:name ctc-name
|
||||||
|
@ -474,14 +475,16 @@
|
||||||
#:projection (listof-*-ho-check (λ (p v) (map p v)))
|
#:projection (listof-*-ho-check (λ (p v) (map p v)))
|
||||||
#:val-first-projection (listof-*-val-first-ho-proj predicate? ctc)
|
#:val-first-projection (listof-*-val-first-ho-proj predicate? ctc)
|
||||||
#:generate (generate ctc)
|
#:generate (generate ctc)
|
||||||
#:exercise (exercise ctc))]
|
#:exercise (exercise ctc)
|
||||||
|
#:list-contract? #t)]
|
||||||
[else
|
[else
|
||||||
(make-contract
|
(make-contract
|
||||||
#:name ctc-name
|
#:name ctc-name
|
||||||
#:first-order fo-check
|
#:first-order fo-check
|
||||||
#:val-first-projection (listof-*-val-first-ho-proj predicate? ctc)
|
#:val-first-projection (listof-*-val-first-ho-proj predicate? ctc)
|
||||||
#:projection (listof-*-ho-check (λ (p v) (map p v)))
|
#:projection (listof-*-ho-check (λ (p v) (map p v)))
|
||||||
#:exercise (exercise ctc))])))
|
#:exercise (exercise ctc)
|
||||||
|
#:list-contract? #t)])))
|
||||||
|
|
||||||
(define (listof-*-val-first-flat-proj predicate? ctc)
|
(define (listof-*-val-first-flat-proj predicate? ctc)
|
||||||
(define vf-proj (get/build-val-first-projection ctc))
|
(define vf-proj (get/build-val-first-projection ctc))
|
||||||
|
@ -593,6 +596,9 @@
|
||||||
cdr-gen
|
cdr-gen
|
||||||
(λ () (cons (car-gen) (cdr-gen))))))
|
(λ () (cons (car-gen) (cdr-gen))))))
|
||||||
|
|
||||||
|
(define (cons/c-list-contract? c)
|
||||||
|
(list-contract? (the-cons/c-tl-ctc c)))
|
||||||
|
|
||||||
(define-struct the-cons/c (hd-ctc tl-ctc))
|
(define-struct the-cons/c (hd-ctc tl-ctc))
|
||||||
(define-struct (flat-cons/c the-cons/c) ()
|
(define-struct (flat-cons/c the-cons/c) ()
|
||||||
#:property prop:custom-write custom-write-property-proc
|
#:property prop:custom-write custom-write-property-proc
|
||||||
|
@ -603,7 +609,8 @@
|
||||||
#:name cons/c-name
|
#:name cons/c-name
|
||||||
#:first-order cons/c-first-order
|
#:first-order cons/c-first-order
|
||||||
#:stronger cons/c-stronger?
|
#:stronger cons/c-stronger?
|
||||||
#:generate cons/c-generate))
|
#:generate cons/c-generate
|
||||||
|
#:list-contract? cons/c-list-contract?))
|
||||||
(define-struct (chaperone-cons/c the-cons/c) ()
|
(define-struct (chaperone-cons/c the-cons/c) ()
|
||||||
#:property prop:custom-write custom-write-property-proc
|
#:property prop:custom-write custom-write-property-proc
|
||||||
#:property prop:chaperone-contract
|
#:property prop:chaperone-contract
|
||||||
|
@ -614,7 +621,8 @@
|
||||||
#:name cons/c-name
|
#:name cons/c-name
|
||||||
#:first-order cons/c-first-order
|
#:first-order cons/c-first-order
|
||||||
#:stronger cons/c-stronger?
|
#:stronger cons/c-stronger?
|
||||||
#:generate cons/c-generate)))
|
#:generate cons/c-generate
|
||||||
|
#:list-contract? cons/c-list-contract?)))
|
||||||
(define-struct (impersonator-cons/c the-cons/c) ()
|
(define-struct (impersonator-cons/c the-cons/c) ()
|
||||||
#:property prop:custom-write custom-write-property-proc
|
#:property prop:custom-write custom-write-property-proc
|
||||||
#:property prop:contract
|
#:property prop:contract
|
||||||
|
@ -624,7 +632,8 @@
|
||||||
#:name cons/c-name
|
#:name cons/c-name
|
||||||
#:first-order cons/c-first-order
|
#:first-order cons/c-first-order
|
||||||
#:stronger cons/c-stronger?
|
#:stronger cons/c-stronger?
|
||||||
#:generate cons/c-generate))
|
#:generate cons/c-generate
|
||||||
|
#:list-contract? cons/c-list-contract?))
|
||||||
|
|
||||||
(define/subexpression-pos-prop (cons/c a b)
|
(define/subexpression-pos-prop (cons/c a b)
|
||||||
(define ctc-car (coerce-contract 'cons/c a))
|
(define ctc-car (coerce-contract 'cons/c a))
|
||||||
|
@ -748,7 +757,8 @@
|
||||||
(((contract-projection arg/c)
|
(((contract-projection arg/c)
|
||||||
(add-list-context blame i))
|
(add-list-context blame i))
|
||||||
v))
|
v))
|
||||||
x))))))
|
x))))
|
||||||
|
#:list-contract? (λ (c) #t)))
|
||||||
|
|
||||||
(define (list/c-chaperone/other-projection c)
|
(define (list/c-chaperone/other-projection c)
|
||||||
(define args (map contract-projection (generic-list/c-args c)))
|
(define args (map contract-projection (generic-list/c-args c)))
|
||||||
|
@ -830,7 +840,8 @@
|
||||||
#:generate list/c-generate
|
#:generate list/c-generate
|
||||||
#:exercise list/c-exercise
|
#:exercise list/c-exercise
|
||||||
#:projection list/c-chaperone/other-projection
|
#:projection list/c-chaperone/other-projection
|
||||||
#:val-first-projection list/c-chaperone/other-val-first-projection)))
|
#:val-first-projection list/c-chaperone/other-val-first-projection
|
||||||
|
#:list-contract? (λ (c) #t))))
|
||||||
|
|
||||||
(struct higher-order-list/c generic-list/c ()
|
(struct higher-order-list/c generic-list/c ()
|
||||||
#:property prop:custom-write custom-write-property-proc
|
#:property prop:custom-write custom-write-property-proc
|
||||||
|
@ -841,7 +852,8 @@
|
||||||
#:generate list/c-generate
|
#:generate list/c-generate
|
||||||
#:exercise list/c-exercise
|
#:exercise list/c-exercise
|
||||||
#:projection list/c-chaperone/other-projection
|
#:projection list/c-chaperone/other-projection
|
||||||
#:val-first-projection list/c-chaperone/other-val-first-projection))
|
#:val-first-projection list/c-chaperone/other-val-first-projection
|
||||||
|
#:list-contract? (λ (c) #t)))
|
||||||
|
|
||||||
(define/subexpression-pos-prop (syntax/c ctc-in)
|
(define/subexpression-pos-prop (syntax/c ctc-in)
|
||||||
(let ([ctc (coerce-flat-contract 'syntax/c ctc-in)])
|
(let ([ctc (coerce-flat-contract 'syntax/c ctc-in)])
|
||||||
|
|
|
@ -168,6 +168,11 @@
|
||||||
[else (option)])])))]
|
[else (option)])])))]
|
||||||
[else #f]))
|
[else #f]))
|
||||||
|
|
||||||
|
(define (single-or/c-list-contract? c)
|
||||||
|
(and (list-contract? (single-or/c-ho-ctc c))
|
||||||
|
(for/and ([c (in-list (single-or/c-flat-ctcs c))])
|
||||||
|
(list-contract? c))))
|
||||||
|
|
||||||
(define-struct single-or/c (name pred flat-ctcs ho-ctc)
|
(define-struct single-or/c (name pred flat-ctcs ho-ctc)
|
||||||
#:property prop:orc-contract
|
#:property prop:orc-contract
|
||||||
(λ (this) (cons (single-or/c-ho-ctc this)
|
(λ (this) (cons (single-or/c-ho-ctc this)
|
||||||
|
@ -186,7 +191,8 @@
|
||||||
#:generate (λ (ctc) (or/c-generate ctc
|
#:generate (λ (ctc) (or/c-generate ctc
|
||||||
(cons (single-or/c-ho-ctc ctc)
|
(cons (single-or/c-ho-ctc ctc)
|
||||||
(single-or/c-flat-ctcs ctc))))
|
(single-or/c-flat-ctcs ctc))))
|
||||||
#:exercise (λ (ctc) (or/c-exercise (list (single-or/c-ho-ctc ctc)))))))
|
#:exercise (λ (ctc) (or/c-exercise (list (single-or/c-ho-ctc ctc))))
|
||||||
|
#:list-contract? single-or/c-list-contract?)))
|
||||||
|
|
||||||
(define-struct (impersonator-single-or/c single-or/c) ()
|
(define-struct (impersonator-single-or/c single-or/c) ()
|
||||||
#:property prop:custom-write custom-write-property-proc
|
#:property prop:custom-write custom-write-property-proc
|
||||||
|
@ -200,7 +206,8 @@
|
||||||
#:generate (λ (ctc) (or/c-generate ctc
|
#:generate (λ (ctc) (or/c-generate ctc
|
||||||
(cons (single-or/c-ho-ctc ctc)
|
(cons (single-or/c-ho-ctc ctc)
|
||||||
(single-or/c-flat-ctcs ctc))))
|
(single-or/c-flat-ctcs ctc))))
|
||||||
#:exercise (λ (ctc) (or/c-exercise (list (single-or/c-ho-ctc ctc))))))
|
#:exercise (λ (ctc) (or/c-exercise (list (single-or/c-ho-ctc ctc))))
|
||||||
|
#:list-contract? single-or/c-list-contract?))
|
||||||
|
|
||||||
(define (multi-or/c-proj ctc)
|
(define (multi-or/c-proj ctc)
|
||||||
(let* ([ho-contracts (multi-or/c-ho-ctcs ctc)]
|
(let* ([ho-contracts (multi-or/c-ho-ctcs ctc)]
|
||||||
|
@ -319,6 +326,12 @@
|
||||||
(andmap contract-stronger? this-ctcs that-ctcs))))
|
(andmap contract-stronger? this-ctcs that-ctcs))))
|
||||||
(generic-or/c-stronger? this that)))
|
(generic-or/c-stronger? this that)))
|
||||||
|
|
||||||
|
(define (mult-or/c-list-contract? c)
|
||||||
|
(and (for/and ([c (in-list (multi-or/c-flat-ctcs c))])
|
||||||
|
(list-contract? c))
|
||||||
|
(for/and ([c (in-list (multi-or/c-ho-ctcs c))])
|
||||||
|
(list-contract? c))))
|
||||||
|
|
||||||
(define-struct multi-or/c (name flat-ctcs ho-ctcs)
|
(define-struct multi-or/c (name flat-ctcs ho-ctcs)
|
||||||
#:property prop:orc-contract
|
#:property prop:orc-contract
|
||||||
(λ (this) (append (multi-or/c-ho-ctcs this)
|
(λ (this) (append (multi-or/c-ho-ctcs this)
|
||||||
|
@ -337,7 +350,8 @@
|
||||||
#:generate (λ (ctc) (or/c-generate ctc
|
#:generate (λ (ctc) (or/c-generate ctc
|
||||||
(append (multi-or/c-ho-ctcs ctc)
|
(append (multi-or/c-ho-ctcs ctc)
|
||||||
(multi-or/c-flat-ctcs ctc))))
|
(multi-or/c-flat-ctcs ctc))))
|
||||||
#:exercise (λ (ctc) (or/c-exercise (multi-or/c-ho-ctcs ctc))))))
|
#:exercise (λ (ctc) (or/c-exercise (multi-or/c-ho-ctcs ctc)))
|
||||||
|
#:list-contract? mult-or/c-list-contract?)))
|
||||||
|
|
||||||
(define-struct (impersonator-multi-or/c multi-or/c) ()
|
(define-struct (impersonator-multi-or/c multi-or/c) ()
|
||||||
#:property prop:custom-write custom-write-property-proc
|
#:property prop:custom-write custom-write-property-proc
|
||||||
|
@ -351,7 +365,8 @@
|
||||||
#:generate (λ (ctc) (or/c-generate ctc
|
#:generate (λ (ctc) (or/c-generate ctc
|
||||||
(append (multi-or/c-ho-ctcs ctc)
|
(append (multi-or/c-ho-ctcs ctc)
|
||||||
(multi-or/c-flat-ctcs ctc))))
|
(multi-or/c-flat-ctcs ctc))))
|
||||||
#:exercise (λ (ctc) (or/c-exercise (multi-or/c-ho-ctcs ctc)))))
|
#:exercise (λ (ctc) (or/c-exercise (multi-or/c-ho-ctcs ctc)))
|
||||||
|
#:list-contract? mult-or/c-list-contract?))
|
||||||
|
|
||||||
(define-struct flat-or/c (pred flat-ctcs)
|
(define-struct flat-or/c (pred flat-ctcs)
|
||||||
#:property prop:custom-write custom-write-property-proc
|
#:property prop:custom-write custom-write-property-proc
|
||||||
|
@ -396,8 +411,11 @@
|
||||||
|
|
||||||
#:first-order
|
#:first-order
|
||||||
(λ (ctc) (flat-or/c-pred ctc))
|
(λ (ctc) (flat-or/c-pred ctc))
|
||||||
#:generate (λ (ctc) (or/c-generate ctc (flat-or/c-flat-ctcs ctc)))))
|
#:generate (λ (ctc) (or/c-generate ctc (flat-or/c-flat-ctcs ctc)))
|
||||||
|
#:list-contract?
|
||||||
|
(λ (ctc)
|
||||||
|
(for/and ([c (in-list (flat-or/c-flat-ctcs ctc))])
|
||||||
|
(list-contract? c)))))
|
||||||
|
|
||||||
|
|
||||||
(define/final-prop (symbols s1 . s2s)
|
(define/final-prop (symbols s1 . s2s)
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
contract-struct-stronger?
|
contract-struct-stronger?
|
||||||
contract-struct-generate
|
contract-struct-generate
|
||||||
contract-struct-exercise
|
contract-struct-exercise
|
||||||
|
contract-struct-list-contract?
|
||||||
|
|
||||||
prop:flat-contract
|
prop:flat-contract
|
||||||
flat-contract-struct?
|
flat-contract-struct?
|
||||||
|
@ -55,7 +56,8 @@
|
||||||
stronger
|
stronger
|
||||||
generate
|
generate
|
||||||
exercise
|
exercise
|
||||||
val-first-projection ]
|
val-first-projection
|
||||||
|
list-contract? ]
|
||||||
#:omit-define-syntaxes)
|
#:omit-define-syntaxes)
|
||||||
|
|
||||||
(define (contract-property-guard prop info)
|
(define (contract-property-guard prop info)
|
||||||
|
@ -121,6 +123,10 @@
|
||||||
(exercise c)
|
(exercise c)
|
||||||
(λ (fuel) (values void '()))))
|
(λ (fuel) (values void '()))))
|
||||||
|
|
||||||
|
(define (contract-struct-list-contract? c)
|
||||||
|
(define prop (contract-struct-property c))
|
||||||
|
((contract-property-list-contract? prop) c))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;
|
;;
|
||||||
;; Chaperone Contract Property
|
;; Chaperone Contract Property
|
||||||
|
@ -215,7 +221,8 @@
|
||||||
#:val-first-projection [get-val-first-projection #f]
|
#:val-first-projection [get-val-first-projection #f]
|
||||||
#:stronger [stronger #f]
|
#:stronger [stronger #f]
|
||||||
#:generate [generate (λ (ctc) (λ (fuel) #f))]
|
#:generate [generate (λ (ctc) (λ (fuel) #f))]
|
||||||
#:exercise [exercise (λ (ctc) (λ (fuel) (values void '())))])
|
#:exercise [exercise (λ (ctc) (λ (fuel) (values void '())))]
|
||||||
|
#:list-contract? [list-contract? (λ (c) #f)])
|
||||||
|
|
||||||
;; this code is here to help me find the combinators that
|
;; this code is here to help me find the combinators that
|
||||||
;; are still using only #:projection and not #:val-first-projection
|
;; are still using only #:projection and not #:val-first-projection
|
||||||
|
@ -242,10 +249,16 @@
|
||||||
get-name get-first-order)])]
|
get-name get-first-order)])]
|
||||||
[stronger (or stronger weakest)])
|
[stronger (or stronger weakest)])
|
||||||
|
|
||||||
(mk get-name get-first-order get-projection stronger generate exercise get-val-first-projection)))
|
(mk get-name get-first-order
|
||||||
|
get-projection stronger
|
||||||
|
generate exercise
|
||||||
|
get-val-first-projection
|
||||||
|
list-contract?)))
|
||||||
|
|
||||||
(define build-contract-property
|
(define build-contract-property
|
||||||
(build-property make-contract-property 'anonymous-contract values))
|
(procedure-rename
|
||||||
|
(build-property make-contract-property 'anonymous-contract values)
|
||||||
|
'build-contract-property))
|
||||||
|
|
||||||
;; Here we'll force the projection to always return the original value,
|
;; Here we'll force the projection to always return the original value,
|
||||||
;; instead of assuming that the provided projection does so appropriately.
|
;; instead of assuming that the provided projection does so appropriately.
|
||||||
|
@ -257,9 +270,11 @@
|
||||||
(λ (v) (p v) v))))))
|
(λ (v) (p v) v))))))
|
||||||
|
|
||||||
(define build-flat-contract-property
|
(define build-flat-contract-property
|
||||||
(build-property (compose make-flat-contract-property make-contract-property)
|
(procedure-rename
|
||||||
'anonymous-flat-contract
|
(build-property (compose make-flat-contract-property make-contract-property)
|
||||||
flat-projection-wrapper))
|
'anonymous-flat-contract
|
||||||
|
flat-projection-wrapper)
|
||||||
|
'build-flat-contract-property))
|
||||||
|
|
||||||
(define (chaperone-projection-wrapper f)
|
(define (chaperone-projection-wrapper f)
|
||||||
(λ (c)
|
(λ (c)
|
||||||
|
@ -279,9 +294,11 @@
|
||||||
(c-proj (blame-add-unknown-context blame)))))
|
(c-proj (blame-add-unknown-context blame)))))
|
||||||
|
|
||||||
(define build-chaperone-contract-property
|
(define build-chaperone-contract-property
|
||||||
(build-property (compose make-chaperone-contract-property make-contract-property)
|
(procedure-rename
|
||||||
'anonymous-chaperone-contract
|
(build-property (compose make-chaperone-contract-property make-contract-property)
|
||||||
chaperone-projection-wrapper))
|
'anonymous-chaperone-contract
|
||||||
|
chaperone-projection-wrapper)
|
||||||
|
'build-chaperone-contract-property))
|
||||||
|
|
||||||
(define (get-any? c) any?)
|
(define (get-any? c) any?)
|
||||||
(define (any? x) #t)
|
(define (any? x) #t)
|
||||||
|
@ -309,7 +326,7 @@
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(define-struct make-contract [ name first-order projection val-first-projection
|
(define-struct make-contract [ name first-order projection val-first-projection
|
||||||
stronger generate exercise ]
|
stronger generate exercise list-contract? ]
|
||||||
#:omit-define-syntaxes
|
#:omit-define-syntaxes
|
||||||
#:property prop:custom-write
|
#:property prop:custom-write
|
||||||
(λ (stct port display?)
|
(λ (stct port display?)
|
||||||
|
@ -324,10 +341,11 @@
|
||||||
#:val-first-projection (lambda (c) (make-contract-val-first-projection c))
|
#:val-first-projection (lambda (c) (make-contract-val-first-projection c))
|
||||||
#:stronger (lambda (a b) ((make-contract-stronger a) a b))
|
#:stronger (lambda (a b) ((make-contract-stronger a) a b))
|
||||||
#:generate (lambda (c) (make-contract-generate c))
|
#:generate (lambda (c) (make-contract-generate c))
|
||||||
#:exercise (lambda (c) (make-contract-exercise c))))
|
#:exercise (lambda (c) (make-contract-exercise c))
|
||||||
|
#:list-contract? (λ (c) (make-contract-list-contract? c))))
|
||||||
|
|
||||||
(define-struct make-chaperone-contract [ name first-order projection val-first-projection
|
(define-struct make-chaperone-contract [ name first-order projection val-first-projection
|
||||||
stronger generate exercise ]
|
stronger generate exercise list-contract? ]
|
||||||
#:omit-define-syntaxes
|
#:omit-define-syntaxes
|
||||||
#:property prop:custom-write
|
#:property prop:custom-write
|
||||||
(λ (stct port display?)
|
(λ (stct port display?)
|
||||||
|
@ -342,10 +360,11 @@
|
||||||
#:val-first-projection (lambda (c) (make-chaperone-contract-val-first-projection c))
|
#:val-first-projection (lambda (c) (make-chaperone-contract-val-first-projection c))
|
||||||
#:stronger (lambda (a b) ((make-chaperone-contract-stronger a) a b))
|
#:stronger (lambda (a b) ((make-chaperone-contract-stronger a) a b))
|
||||||
#:generate (lambda (c) (make-chaperone-contract-generate c))
|
#:generate (lambda (c) (make-chaperone-contract-generate c))
|
||||||
#:exercise (lambda (c) (make-chaperone-contract-exercise c))))
|
#:exercise (lambda (c) (make-chaperone-contract-exercise c))
|
||||||
|
#:list-contract? (λ (c) (make-chaperone-contract-list-contract? c))))
|
||||||
|
|
||||||
(define-struct make-flat-contract [ name first-order projection val-first-projection
|
(define-struct make-flat-contract [ name first-order projection val-first-projection
|
||||||
stronger generate exercise ]
|
stronger generate exercise list-contract? ]
|
||||||
#:omit-define-syntaxes
|
#:omit-define-syntaxes
|
||||||
#:property prop:custom-write
|
#:property prop:custom-write
|
||||||
(λ (stct port display?)
|
(λ (stct port display?)
|
||||||
|
@ -360,7 +379,8 @@
|
||||||
#:projection (lambda (c) (make-flat-contract-projection c))
|
#:projection (lambda (c) (make-flat-contract-projection c))
|
||||||
#:stronger (lambda (a b) ((make-flat-contract-stronger a) a b))
|
#:stronger (lambda (a b) ((make-flat-contract-stronger a) a b))
|
||||||
#:generate (lambda (c) (make-flat-contract-generate c))
|
#:generate (lambda (c) (make-flat-contract-generate c))
|
||||||
#:exercise (lambda (c) (make-flat-contract-exercise c))))
|
#:exercise (lambda (c) (make-flat-contract-exercise c))
|
||||||
|
#:list-contract? (λ (c) (make-flat-contract-list-contract? c))))
|
||||||
|
|
||||||
(define ((build-contract mk default-name)
|
(define ((build-contract mk default-name)
|
||||||
#:name [name #f]
|
#:name [name #f]
|
||||||
|
@ -369,7 +389,8 @@
|
||||||
#:val-first-projection [val-first-projection #f]
|
#:val-first-projection [val-first-projection #f]
|
||||||
#:stronger [stronger #f]
|
#:stronger [stronger #f]
|
||||||
#:generate [generate (λ (ctc) (λ (fuel) #f))]
|
#:generate [generate (λ (ctc) (λ (fuel) #f))]
|
||||||
#:exercise [exercise (λ (ctc) (λ (fuel) (values void '())))])
|
#:exercise [exercise (λ (ctc) (λ (fuel) (values void '())))]
|
||||||
|
#:list-contract? [list-contract? (λ (ctc) #f)])
|
||||||
|
|
||||||
(let* ([name (or name default-name)]
|
(let* ([name (or name default-name)]
|
||||||
[first-order (or first-order any?)]
|
[first-order (or first-order any?)]
|
||||||
|
@ -379,7 +400,11 @@
|
||||||
(val-first-first-order-projection name first-order)))]
|
(val-first-first-order-projection name first-order)))]
|
||||||
[stronger (or stronger as-strong?)])
|
[stronger (or stronger as-strong?)])
|
||||||
|
|
||||||
(mk name first-order projection val-first-projection stronger generate exercise)))
|
(mk name first-order
|
||||||
|
projection val-first-projection
|
||||||
|
stronger
|
||||||
|
generate exercise
|
||||||
|
list-contract?)))
|
||||||
|
|
||||||
(define ((get-val-first-first-order-projection get-name get-first-order) c)
|
(define ((get-val-first-first-order-projection get-name get-first-order) c)
|
||||||
(val-first-first-order-projection (get-name c) (get-first-order c)))
|
(val-first-first-order-projection (get-name c) (get-first-order c)))
|
||||||
|
@ -403,12 +428,19 @@
|
||||||
(contract-struct-projection b)))
|
(contract-struct-projection b)))
|
||||||
|
|
||||||
(define make-contract
|
(define make-contract
|
||||||
(build-contract make-make-contract 'anonymous-contract))
|
(procedure-rename
|
||||||
|
(build-contract make-make-contract 'anonymous-contract)
|
||||||
|
'make-contract))
|
||||||
|
|
||||||
(define make-chaperone-contract
|
(define make-chaperone-contract
|
||||||
(build-contract make-make-chaperone-contract 'anonymous-chaperone-contract))
|
(procedure-rename
|
||||||
|
(build-contract make-make-chaperone-contract 'anonymous-chaperone-contract)
|
||||||
|
'make-chaperone-contract))
|
||||||
|
|
||||||
(define make-flat-contract (build-contract make-make-flat-contract 'anonymous-flat-contract))
|
(define make-flat-contract
|
||||||
|
(procedure-rename
|
||||||
|
(build-contract make-make-flat-contract 'anonymous-flat-contract)
|
||||||
|
'make-flat-contract))
|
||||||
|
|
||||||
;; property should be bound to a function that accepts the contract and
|
;; property should be bound to a function that accepts the contract and
|
||||||
;; returns a list of contracts that were the original arguments to the or/c
|
;; returns a list of contracts that were the original arguments to the or/c
|
||||||
|
|
Loading…
Reference in New Issue
Block a user