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

How to convert from value with Any type to Real?

我正在玩 Racket-Stamps,它是打字和普通 Racket 的混合体。

我正在编写一个新功能,下面的代码试图调用一个带有 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))

这是错误:

类型检查器:“apply”中函数的错误参数: 域:a b ... b #F * 参数:(任何列表)* 在:(应用值(边界))

那么如何将 Listof Any 转换为 Listof Real

此处的 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))))