Racket 如何";“承诺”;值将是某一类型

Racket 如何";“承诺”;值将是某一类型,racket,typed-racket,Racket,Typed 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])) 如果输入为“空”,则返回随机颜色,否则返回输入,如何阻止类型检查器说s(在[else s]中)可以是图像颜色或“空”,而不是预期的图像颜色?还

如果我在typed/racket中有此功能:

(: random-if-empty (-> (U Image-Color "empty") Image-Color))
(define (random-if-empty s)
  (cond
    [(equal? s "empty") (random-color)]
    [else s]))
如果输入为
“空”
,则返回随机颜色,否则返回输入,如何阻止类型检查器说
s
(在
[else s]
中)可以是
图像颜色
“空”
,而不是预期的
图像颜色
?还是有更好的方法来实现这一点?我正在使用
typed/2htdp/image
库,它是
图像颜色
的来源。

您可以利用它告诉类型检查器,在第二种情况下,您的
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]))
为什么
字符串?
工作而不
(等于?s“空”)
?我不知道,但我想打字球拍没那么聪明

你也可以使用


如果您的类型真的很复杂,您可能不得不求助于,它就像断言一样编写。但我已经按照偏好的顺序给出了这些解决方案。强制转换应该是最后的手段。

谓词可以通知类型系统变量是或不是特定值,但是,这只适用于特定类型的特定值。它适用于一些简单类型(布尔、符号、空列表、void和
0
1
),但不适用于大多数其他数据类型,包括字符串

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

解决这个问题的方法是以不同的方式为
字符串“empty”
创建自己的谓词。类型化racket提供了一种形式,可以将一些简单的“平面”类型转换为谓词。您可以这样使用它:

(define my-empty-pred? (make-predicate "empty"))
这个新谓词将能够更直接地告诉类型系统,如果
(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]))

我想这对平等不起作用?因为它不是谓词。如果
图像颜色可以是字符串,则将其更改为
字符串?
会更改程序的行为。由于在
typed/2htdp/image
中可以,Gibstick的第一个解决方案是错误的。
(: random-if-empty (-> (U Image-Color "empty") Image-Color))
(define (random-if-empty s)
  (cond
    [(my-empty-pred? s) (random-color)]
    [else s]))