如何"承诺"一个值将是某种类型

时间:2017-05-10 04:30:36

标签: racket typed-racket

如果我在打字/球拍中有这个功能:

(: 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来自哪里。

2 个答案:

答案 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,01),但它不适用于大多数其他数据类型,包括字符串。

(这可能与字符串可变性有关,我不确定。)

解决此问题的方法是以不同的方式为"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]))