如何将Any类型的值转换为Real?

时间:2017-12-02 16:17:09

标签: racket typed-racket

我正在玩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

1 个答案:

答案 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))))