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

How to combine an occurrence type of `VectorTop` with the vector's element type?

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

(: 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

乍一看这似乎很奇怪,但事情非常不同,因为向量是可变的。

如果某物是 (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。相反,类型 VectorTop 不会为您提供任何 "set" 信息,因此 VectorTop 本身不允许突变。