我正在玩Racket-Stamps,它是有型和常规球拍的混合体。
我正在写一个新功能,下面的代码试图用一个Reals列表来调用一个函数,但是因为这个列表来自无类型的racket,它实际上是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)))
在另一个调用上面代码的文件中:
(bounding '(-20 -100 100 2))
这是错误:
Type Checker:在`apply'中运行的参数不正确: 域名:a b ... b #F * 参数:(任何名单)* in :(应用值(边界))
那么如何将Listof Any
转换为Listof Real
?
答案 0 :(得分:1)
这里的apply
函数被赋予一个任意长度的列表作为输入,但是上下文恰好需要4个值。如果列表的长度不是4,则会失败。
似乎你的意思是bounding
包含空列表或 4个实数的列表。
(: bounding : (Parameterof (U Null (List Real Real Real Real))))
(define bounding (make-parameter '()))
然后,每当您的程序测试(bounding)
的内容是否为空,然后依赖于它是4个数字的列表时,您需要先将值放在局部变量中,以便Typed Racket看到(not (empty? ...))
测试与其下方使用之间的联系。
换句话说,转换模式
(if (not (empty? (bounding)))
(.... (bounding) ....)
....)
向
(let ([bounding-v (bounding)])
(if (not (empty? bounding-v))
(.... bounding-v ....)
....))
在您的示例中,该转换提供:
(: 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))))