A simplified version of my desired output:
{
"dynamic-name": {
"type": "type",
"fields": {
"inner-dynamic-name": {
"type": "inner-type",
"analyzer": "analyzer"
}
}
}
}
And here's the Dhall code I've written to generate that:
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
However, when passing my Dhall configuration to dhall-to-json
I get the following error:
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"
}
}
I'm running version 1.7.6 of dhall-to-json
. What am I doing wrong?
(Disregard: I need to include more words in order to be allowed to post my question, but anything more seems superfluous. These last sentences is me being Hackerman.)
I'm copying my answer from https://github.com/dhall-lang/dhall-haskell/issues/2259 to here:
dhall-to-json
cannot handle custom recursive types directly, but it can handle one distinguished recursive type, which is Prelude.JSON.Type
, so something like this would work:
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
… and dhall-to-json
accepts that:
$ dhall-to-json --file ./example.dhall
{
"dynamic-name": {
"fields": [
{
"inner-dynamic-name": {
"analyzer": "analyzer",
"type": "inner-type"
}
}
],
"type": "type"
}
}