Я пытаюсь использовать пакет json
в Typed Racket, но у меня возникли проблемы с обработкой ввода предиката 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
, вероятно, достаточно здесь, но, похоже, не существует.