如何在Typed Racket中使用JSON的`jsexpr?`谓词?

时间:2014-12-04 21:57:34

标签: racket typed-racket

我尝试在Typed Racket中使用json包,但我在处理如何键入jsexpr?谓词方面遇到了一些麻烦。我的第一次尝试只是使用#:opaque

(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?!幸运的是,存在define-predicate来为我生成该函数。遗憾的是,它不适用于JSExpr类型,因为谓词需要一个平坦的契约,而HashTable等潜在的可变数据结构需要签约合同。

好吧,那么为jsexpr?输入实际的JSExpr谓词到出现类型呢?

(require/typed json
               [jsexpr? (-> Any Boolean : JSExpr)])

不幸的是,也不起作用,因为过滤器无法在require/typed中使用。

我理解真正的问题很可能源于HashTable可变的事实,但这不是我可以改变的事情。我想我可以编写我自己的(-> Any Boolean : JSExpr)函数,但这会破坏使用该库的目的。

是否以任何方式使这项工作?一个简单的ImmutableHashTable类型可能就足够了,但似乎并不存在。

1 个答案:

答案 0 :(得分:0)

来自邮件列表:

  

问题是,键入的球拍不知道类型为String的值是否为JSExpr类型,因此您必须将(assert x jsexpr?)放在您想要视为jsexpr的所有内容周围