[plt-scheme] Dynamic Contracts
Chris, you should look at the ->d and ->r contract forms in the
contract.ss library. They allow higher-order function contracts whose
result position can depend on the values of the inputs. For instance,
in your case:
(provide/contract
[make-list (natural-number/c any/c . ->d .
(lambda (count val)
(and/c
(listof (lambda (elem) (eq? elem val)))
(lambda (list) (= (length list) count)))))])
If I've written it right, this enforces that the result is a list,
that it contains only the given value, and that its length is the
given count.
--Carl
On 7/21/06, Chris Warrington <gcw5217 at rice.edu> wrote:
> Does contract.ss support what I want to call "dynamic contracts?"
>
> Consider this function:
> ; make-list : natural-number X -> [X]
> ; Creates a list of the given length in which each element
> ; is the provided element.
> (define (make-list count val) ...)
>
> Using provide/contract (yes, I'm doing this in a module), I can attach a simple
> contract to this:
> (provide/contract [make-list (natural-number/c any/c . -> . (listof any/c))])
>
> However, this contract can be made stronger. For example, the length of the list
> should be equal to count. However, I can't find a good way to do this.
> Thus far, the best I have is this:
>
> ; dc:make-list
> ; Dynamic contract for make-list
> (define (dc:make-list count val)
> ((contract (natural-number/c any/c . -> . (and/c (listof any/c)
> (λ (lst) (= (length lst)
> count))))
> make-list
> 'callee
> 'caller)
> count val))
>
> Is there an easier way to do these "dynamic contracts?" How would one go about
> enforcing the type contraint in this case (i.e., the list should be of the same
> type as val)?
>
> --
> Chris Warrington <chrisw at rice.edu>
> (away from his normal computer)