使用 Dhall 将递归类型编码为 JSON
Encoding recursive types to JSON using Dhall
我想要的输出的简化版本:
{
"dynamic-name": {
"type": "type",
"fields": {
"inner-dynamic-name": {
"type": "inner-type",
"analyzer": "analyzer"
}
}
}
}
这是我编写的 Dhall 代码:
let Field
: Type
= ∀(Field : Type) →
∀ ( Leaf
: { mapKey : Text, mapValue : { type : Text, analyzer : Optional Text } } →
Field
) →
∀ ( Node
: { mapKey : Text, mapValue : { type : Text, fields : List Field } } →
Field
) →
Field
let example
: Field
= λ(Field : Type) →
λ ( Leaf
: { mapKey : Text, mapValue : { type : Text, analyzer : Optional Text } } →
Field
) →
λ ( Node
: { mapKey : Text, mapValue : { type : Text, fields : List Field } } →
Field
) →
Node
{ mapKey = "dynamic-name"
, mapValue =
{ type = "type"
, fields =
[ Leaf
{ mapKey = "inner-dynamic-name"
, mapValue =
{ type = "inner-type", analyzer = Some "analyzer" }
}
]
}
}
in example
但是,当我将 Dhall 配置传递给 dhall-to-json
时,出现以下错误:
Error: Cannot translate to JSON
Explanation: Only primitive values, records, unions, ❰List❱s, and ❰Optional❱
values can be translated from Dhall to JSON
The following Dhall expression could not be translated to JSON:
↳ λ(_ : Type) →
λ ( _
: { mapKey : Text, mapValue : { analyzer : Optional Text, type : Text } } →
_@1
) →
λ(_ : { mapKey : Text, mapValue : { fields : List _@1, type : Text } } → _@2) →
_
{ mapKey = "dynamic-name"
, mapValue =
{ fields =
[ _@1
{ mapKey = "inner-dynamic-name"
, mapValue = { analyzer = Some "analyzer", type = "inner-type" }
}
]
, type = "type"
}
}
我是 运行 dhall-to-json
的 1.7.6 版。我做错了什么?
(无视:我需要包含更多的单词才能被允许 post 我的问题,但再多的话似乎都是多余的。最后几句话是我是 Hackerman。)
我正在将 https://github.com/dhall-lang/dhall-haskell/issues/2259 的答案复制到此处:
dhall-to-json
无法直接处理自定义递归类型,但它可以处理一种可区分的递归类型,即 Prelude.JSON.Type
,因此这样的事情会起作用:
let JSON =
https://prelude.dhall-lang.org/JSON/package.dhall
sha256:5f98b7722fd13509ef448b075e02b9ff98312ae7a406cf53ed25012dbc9990ac
let Field
: Type
= ∀(Field : Type) →
∀ ( Leaf
: { mapKey : Text
, mapValue : { type : Text, analyzer : Optional Text }
} →
Field
) →
∀ ( Node
: { mapKey : Text, mapValue : { type : Text, fields : List Field } } →
Field
) →
Field
let example
: Field
= λ(Field : Type) →
λ ( Leaf
: { mapKey : Text
, mapValue : { type : Text, analyzer : Optional Text }
} →
Field
) →
λ ( Node
: { mapKey : Text, mapValue : { type : Text, fields : List Field } } →
Field
) →
Node
{ mapKey = "dynamic-name"
, mapValue =
{ type = "type"
, fields =
[ Leaf
{ mapKey = "inner-dynamic-name"
, mapValue =
{ type = "inner-type", analyzer = Some "analyzer" }
}
]
}
}
let Field/toJSON
: Field → JSON.Type
= λ(field : Field) →
field
JSON.Type
( λ ( args
: { mapKey : Text
, mapValue : { type : Text, analyzer : Optional Text }
}
) →
JSON.object
[ { mapKey = args.mapKey
, mapValue =
JSON.object
( toMap
{ type = JSON.string args.mapValue.type
, analyzer =
merge
{ None = JSON.null, Some = JSON.string }
args.mapValue.analyzer
}
)
}
]
)
( λ ( args
: { mapKey : Text
, mapValue : { type : Text, fields : List JSON.Type }
}
) →
JSON.object
[ { mapKey = args.mapKey
, mapValue =
JSON.object
( toMap
{ type = JSON.string args.mapValue.type
, fields = JSON.array args.mapValue.fields
}
)
}
]
)
in Field/toJSON example
… 并且 dhall-to-json
接受:
$ dhall-to-json --file ./example.dhall
{
"dynamic-name": {
"fields": [
{
"inner-dynamic-name": {
"analyzer": "analyzer",
"type": "inner-type"
}
}
],
"type": "type"
}
}
我想要的输出的简化版本:
{
"dynamic-name": {
"type": "type",
"fields": {
"inner-dynamic-name": {
"type": "inner-type",
"analyzer": "analyzer"
}
}
}
}
这是我编写的 Dhall 代码:
let Field
: Type
= ∀(Field : Type) →
∀ ( Leaf
: { mapKey : Text, mapValue : { type : Text, analyzer : Optional Text } } →
Field
) →
∀ ( Node
: { mapKey : Text, mapValue : { type : Text, fields : List Field } } →
Field
) →
Field
let example
: Field
= λ(Field : Type) →
λ ( Leaf
: { mapKey : Text, mapValue : { type : Text, analyzer : Optional Text } } →
Field
) →
λ ( Node
: { mapKey : Text, mapValue : { type : Text, fields : List Field } } →
Field
) →
Node
{ mapKey = "dynamic-name"
, mapValue =
{ type = "type"
, fields =
[ Leaf
{ mapKey = "inner-dynamic-name"
, mapValue =
{ type = "inner-type", analyzer = Some "analyzer" }
}
]
}
}
in example
但是,当我将 Dhall 配置传递给 dhall-to-json
时,出现以下错误:
Error: Cannot translate to JSON
Explanation: Only primitive values, records, unions, ❰List❱s, and ❰Optional❱
values can be translated from Dhall to JSON
The following Dhall expression could not be translated to JSON:
↳ λ(_ : Type) →
λ ( _
: { mapKey : Text, mapValue : { analyzer : Optional Text, type : Text } } →
_@1
) →
λ(_ : { mapKey : Text, mapValue : { fields : List _@1, type : Text } } → _@2) →
_
{ mapKey = "dynamic-name"
, mapValue =
{ fields =
[ _@1
{ mapKey = "inner-dynamic-name"
, mapValue = { analyzer = Some "analyzer", type = "inner-type" }
}
]
, type = "type"
}
}
我是 运行 dhall-to-json
的 1.7.6 版。我做错了什么?
(无视:我需要包含更多的单词才能被允许 post 我的问题,但再多的话似乎都是多余的。最后几句话是我是 Hackerman。)
我正在将 https://github.com/dhall-lang/dhall-haskell/issues/2259 的答案复制到此处:
dhall-to-json
无法直接处理自定义递归类型,但它可以处理一种可区分的递归类型,即 Prelude.JSON.Type
,因此这样的事情会起作用:
let JSON =
https://prelude.dhall-lang.org/JSON/package.dhall
sha256:5f98b7722fd13509ef448b075e02b9ff98312ae7a406cf53ed25012dbc9990ac
let Field
: Type
= ∀(Field : Type) →
∀ ( Leaf
: { mapKey : Text
, mapValue : { type : Text, analyzer : Optional Text }
} →
Field
) →
∀ ( Node
: { mapKey : Text, mapValue : { type : Text, fields : List Field } } →
Field
) →
Field
let example
: Field
= λ(Field : Type) →
λ ( Leaf
: { mapKey : Text
, mapValue : { type : Text, analyzer : Optional Text }
} →
Field
) →
λ ( Node
: { mapKey : Text, mapValue : { type : Text, fields : List Field } } →
Field
) →
Node
{ mapKey = "dynamic-name"
, mapValue =
{ type = "type"
, fields =
[ Leaf
{ mapKey = "inner-dynamic-name"
, mapValue =
{ type = "inner-type", analyzer = Some "analyzer" }
}
]
}
}
let Field/toJSON
: Field → JSON.Type
= λ(field : Field) →
field
JSON.Type
( λ ( args
: { mapKey : Text
, mapValue : { type : Text, analyzer : Optional Text }
}
) →
JSON.object
[ { mapKey = args.mapKey
, mapValue =
JSON.object
( toMap
{ type = JSON.string args.mapValue.type
, analyzer =
merge
{ None = JSON.null, Some = JSON.string }
args.mapValue.analyzer
}
)
}
]
)
( λ ( args
: { mapKey : Text
, mapValue : { type : Text, fields : List JSON.Type }
}
) →
JSON.object
[ { mapKey = args.mapKey
, mapValue =
JSON.object
( toMap
{ type = JSON.string args.mapValue.type
, fields = JSON.array args.mapValue.fields
}
)
}
]
)
in Field/toJSON example
… 并且 dhall-to-json
接受:
$ dhall-to-json --file ./example.dhall
{
"dynamic-name": {
"fields": [
{
"inner-dynamic-name": {
"analyzer": "analyzer",
"type": "inner-type"
}
}
],
"type": "type"
}
}