使用适用于类型化球拍的构建结构

时间:2018-07-16 12:06:49

标签: struct polymorphism typed-racket

我正在尝试使用Typed Racket中的apply构建结构列表,但无法弄清楚如何使其工作。我的猜测是,它与多态函数的问题有关,但我无法解决。

这有效:

(struct tt ([a : Integer]
            [b : Integer]))

(apply tt '(1 2))

但这不是(编辑):

(struct tt2 ([a : String]
             [b : (Vectorof Any)]))

(apply tt2 (list "A" (vector 1 2 2)))

出现错误:

 /usr/share/racket/collects/racket/private/kw.rkt:979:25: Type Checker: Bad
arguments to function in `apply':
Domain: String (Vectorof Any)
Arguments:  (List String (Vector Integer Integer Integer))

  in: (#%app apply tt23 (#%app list (quote "A") (#%app vector (quote 1) (quote 2) (quote 2))))

对此有什么解决办法吗?

1 个答案:

答案 0 :(得分:2)

向量是一种可变的数据结构,对向量进行变异的可能性使类型检查变得不那么直观。

(Vectorof Integer)不能用作(Vectorof Any),因为以后(Vectorof Any)可能会被突变为包括非整数。这样的程序不会进行类型检查

#lang typed/racket
(struct tt2 ([a : Integer]
             [b : (Vectorof Any)]))

(: v (Vectorof Integer)
(define v (vector 1 2 2))
(apply tt2 (list 1 v))

因为这样做,某人可以写(vector-set! (tt2-b ....) 0 "not a number"),然后v里面的类型错误。

解决方案是在创建矢量时将每个矢量注释为正确的类型。这意味着要做这些事情之一:

  1. (vector ....)代替(ann (vector ....) (Vectorof Any))
  2. 如果向量是直接作为变量v创建的,则将(define v (vector ....))替换为(define v : (Vectorof Any) (vector ....))

例如:

#lang typed/racket
(struct tt2 ([a : Integer]
             [b : (Vectorof Any)]))

(apply tt2 (list 1 (ann (vector 1 2 2) (Vectorof Any))))

请记住,通常对于向量之类的可变而言这是必需的,而对于诸如列表之类的不可变之物则不是必需的。