I'm playing with Racket-Stamps, which is a mix of typed and regular Racket.
I'm writing a new feature and the code below attempts to call a function with a list of Reals, however because this list comes from untyped racket, it is actually a list of Any:
(define bounding (make-parameter '()))
;; snip
(when (not (empty? (bounding)))
(let-values ([(x1 y1 x2 y2) (apply values (bounding))])
(send pr set-bounding x1 y1 x2 y2)))
And in another file that calls the code above:
(bounding '(-20 -100 100 2))
Here's the error:
Type Checker: Bad arguments to function in `apply': Domains: a b ... b #f * Arguments: (Listof Any) * in: (apply values (bounding))
So how do I convert the Listof Any
to a Listof Real
?
The apply
function here is given an arbitrary-length list as input, but the context expects exactly 4 values. If the list had any length other than 4, it would fail.
It seems like you meant for bounding
to contain either the empty list or a list of exactly 4 real numbers.
(: bounding : (Parameterof (U Null (List Real Real Real Real))))
(define bounding (make-parameter '()))
Then every time your program tests whether the contents of (bounding)
are empty and then relies on it being a list of 4 numbers, you need to put the value in a local variable first, so that Typed Racket sees the connection between the (not (empty? ...))
test and the use below it.
In other words, transform the pattern
(if (not (empty? (bounding)))
(.... (bounding) ....)
....)
Into
(let ([bounding-v (bounding)])
(if (not (empty? bounding-v))
(.... bounding-v ....)
....))
In your example, that transformation gives:
(: bounding : (Parameterof (U Null (List Real Real Real Real))))
(define bounding (make-parameter '()))
....
(let ([bounding-v (bounding)])
(when (not (empty? bounding-v))
(let-values ([(x1 y1 x2 y2) (apply values bounding-v)])
(send pr set-bounding x1 y1 x2 y2))))
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments