如何将 `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
本身不允许突变。
这是我无法进行类型检查的函数的最小示例:
(: 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
本身不允许突变。