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