问题描述
我想要的输出的简化版本:
{
"dynamic-name": {
"type": "type","fields": {
"inner-dynamic-name": {
"type": "inner-type","analyzer": "analyzer"
}
}
}
}
let Field
: Type
= ∀(Field : Type) →
∀ ( Leaf
: { mapKey : Text,mapValue : { type : Text,analyzer : Optional Text } } →
Field
) →
∀ ( Node
: { mapKey : Text,fields : List Field } } →
Field
) →
Field
let example
: Field
= λ(Field : Type) →
λ ( Leaf
: { mapKey : Text,analyzer : Optional Text } } →
Field
) →
λ ( Node
: { mapKey : 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 版。我做错了什么?
(忽略:我需要包含更多单词才能发布我的问题,但任何更多似乎都是多余的。最后几句话是我是黑客。)
解决方法
我将我的回答从 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,fields : List Field } } →
Field
) →
Field
let example
: Field
= λ(Field : Type) →
λ ( Leaf
: { mapKey : Text,analyzer : Optional Text }
} →
Field
) →
λ ( Node
: { mapKey : 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,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,fields : List JSON.Type }
}
) →
JSON.object
[ { mapKey = args.mapKey,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"
}
}