如何使用JSON';s`jsexpr?`带类型化Racket的谓词?

如何使用JSON';s`jsexpr?`带类型化Racket的谓词?,racket,typed-racket,Racket,Typed Racket,我试图在Typed Racket中使用json包,但在处理如何键入jsexpr?谓词时遇到了一些问题。我的第一次尝试只是简单地使用了:不透明 (require/typed json [#:opaque JSExpr jsexpr?]) 问题在于jsexpr不是一个结构,jsexpr?只是一个测试给定值是否适合某个结构的谓词。实际上,JSExpr类型应该是这样的 (define-type JSExpr (U 'null Bo

我试图在Typed Racket中使用
json
包,但在处理如何键入
jsexpr?
谓词时遇到了一些问题。我的第一次尝试只是简单地使用了
:不透明

(require/typed json
               [#:opaque JSExpr jsexpr?])
问题在于
jsexpr
不是一个结构,
jsexpr?
只是一个测试给定值是否适合某个结构的谓词。实际上,
JSExpr
类型应该是这样的

(define-type JSExpr (U
                     'null Boolean String Integer Inexact-Real
                     (Listof JSExpr) (HashTable Symbol JSExpr)))
因此,我只使用
JSExpr
类型,但仍然存在一个问题。现在我有了一个
(U JSExpr EOF)
类型,我需要将它转换为
JSExpr
类型(如果我得到EOF,我想抛出一个异常)。因此,我想这样做:

(cond
 [(jsexpr? json-data) json-data]
 [else (error "failed to parse JSON data")])
这应该适用于Racket的事件类型,但现在我没有定义
jsexpr?
!幸运的是,存在为我生成该函数的方法。不幸的是,它不适用于
JSExpr
类型,因为谓词需要一个平面契约,而潜在的可变数据结构,如
HashTable
需要伴侣契约

好的,那么为
jsexpr
的出现类型键入实际的
jsexpr?
谓词怎么样

(require/typed json
               [jsexpr? (-> Any Boolean : JSExpr)])
不幸的是,这也不起作用,因为过滤器不能在
require/typed
中使用

我知道真正的问题很可能是因为
哈希表
是可变的,但这不是我可以改变的。我想我可以编写自己的
(>任何布尔值:JSExpr)
函数,但这会有点违背使用库的目的

有什么办法能让这一切顺利进行吗?一个简单的
ImmutableHashTable
类型在这里可能就足够了,但它似乎并不存在。

来自邮件列表:

问题是,typed racket不知道例如String类型的值是否为JSExpr类型,因此您必须将
(assert x JSExpr?)
放在希望作为JSExpr处理的所有内容周围


在racket lang邮件列表或IRC上询问@samth或vincent或asumu……在我看来,如果
JSexpr
是一个
struct
,那么基本上需要事先建立一个模式,这将有点违背使用JSON的目的。