如果我在打字/球拍中有这个功能:
(: random-if-empty (-> (U Image-Color "empty") Image-Color))
(define (random-if-empty s)
(cond
[(equal? s "empty") (random-color)]
[else s]))
如果输入为"empty"
,则会返回随机颜色,否则会返回它的输入,如何阻止类型检查器说s
(在{ {1}})可以是[else s]
或 Image-Color
而不是预期的"empty"
?或者总体上有更好的方法吗?我使用的是Image-Color
库,typed/2htdp/image
来自哪里。
答案 0 :(得分:0)
您可以利用occurrence typing告诉类型检查器,第二种情况下的pears
不能是字符串。
s
为什么#lang typed/racket
(require typed/2htdp/image)
(define (random-color) : Image-Color
(color 0 0 0)) ;; dummy
(: random-if-empty (-> (U Image-Color "empty") Image-Color))
(define (random-if-empty s)
(cond
[(string? s) (random-color)]
[else s]))
有效而非string?
?我不知道,但我觉得Typed Racket并不聪明。
您也可以使用assertions
(equal? s "empty)"
如果你的类型非常复杂,你可能不得不求助于casting,它们就像断言一样。但我按照偏好顺序给出了这些解决方案。铸造应该是最后的手段。
答案 1 :(得分:0)
equal?
谓词可以通知类型系统变量是否是某个值,但是,这仅适用于某些类型的某些值。它适用于一些简单类型(布尔值,符号,空列表,void,0
和1
),但它不适用于大多数其他数据类型,包括字符串。
(这可能与字符串可变性有关,我不确定。)
解决此问题的方法是以不同的方式为"empty"
字符串创建自己的谓词。键入的球拍提供make-predicate
形式,可以变成一些简单的"平坦的"键入谓词。您可以像这样使用它:
(define my-empty-pred? (make-predicate "empty"))
此新谓词将能够更直接地使用occurrence typing告诉类型系统,如果(my-empty-pred? x)
返回true,则x
的类型为"empty"
,如果它返回false,然后x
的类型不应包含"empty"
。所以你可以在你的例子中使用它,如:
(: random-if-empty (-> (U Image-Color "empty") Image-Color))
(define (random-if-empty s)
(cond
[(my-empty-pred? s) (random-color)]
[else s]))