如何将'VectorTop`的出现类型与向量的元素类型相结合?

时间:2017-09-17 23:27:12

标签: racket typed-racket

这是我无法进行类型检查的函数的最小示例:

(: int-sequence-to-vector ((Sequenceof Integer) -> (Vectorof Integer)))
(define (int-sequence-to-vector seq)
  (cond
    [(vector? seq) seq] ; This line is the problem.
    [else (for/vector : (Vectorof Integer) ([v seq]) v)]))

目标是保留序列元素的类型(因此,函数范围应为-> (Vectorof Integer)而不是-> Vectortop),并使向量上的操作成为无操作。

错误是:

Type Checker: type mismatch
  expected: (Vectorof Integer)
  given: (∩ (Sequenceof Integer) VectorTop) in: seq

我不确定VectorTop(Vectorof Any)之间有什么区别,而且在我看来(Sequenceof T)也是VectorTop必须是(Vectorof T)

以下内容围绕值添加了cast

(: int-sequence-to-vector ((Sequenceof Integer) -> (Vectorof Integer)))
(define (int-sequence-to-vector seq)
  (cond
    [(vector? seq) (cast seq (Vectorof Integer))]
    [else (for/vector : (Vectorof Integer) ([v seq]) v)]))

但这并没有帮助:

Type Checker: Type (∩ (Sequenceof Integer) VectorTop) could not be 
converted to a contract: 
Intersection type contract contains more than 1 non-flat contract: 
(∩ (Sequenceof Integer) VectorTop) in: seq

1 个答案:

答案 0 :(得分:1)

这一开始可能看起来很奇怪,但事情却非常不同,因为载体是可变的。

如果某个内容是wx.CB_SORT,那只表示当获取某个元素时,它就是一个整数。但类型(Sequenceof Integer)意味着更多。这意味着当您设置元素时,您可以将其设置为您想要的任何整数。

(Vectorof Integer)

因此,使用载体进行类型检查必须比使用序列更严格。

例如,对于序列,您可以将(: mutate-vector-of-integer : (Vectorof Integer) -> Void) (define (mutate-vector-of-integer voi) (vector-set! voi 0 -987654321)) ; can set it to any integer 传递给期望(Sequenceof Byte)的函数,并且没有问题。即使将(Sequenceof Integer)传递给期望(Vectorof Byte)的函数也可以,但这只是因为(Sequenceof Integer)本身并不允许您改变序列。

但是,由于可能存在突变,因此无法使用Sequenceof作为(Vectorof Byte)。对此的技术术语是(Vectorof Integer) 不变

Vectorof

这也是(define vob : (Vectorof Byte) (vector 1 2 3)) (expect-vector-of-integer vob) ;Type Checker: type mismatch ; expected: (Vectorof Integer) ; given: (Vectorof Byte) in: vob VectorTop不同的原因。类型(Vectorof Any)会告诉您两件事:当您获得元素时,它的类型为(Vectorof Any),而当您设置元素时,您可以使用Any。相比之下,Any类型并没有为您提供任何" set"信息,因此VectorTop本身不允许变异。