Closed mbj closed 6 years ago
@mbj: There is a way to do this. If you use a sum type to unify the two mismatching types then dhall-to-json
will strip the tag when converting to JSON. For example:
-- example.dhall
let Union = < Left : Natural | Right : { `Fn::GetAZs` : { Ref : Text } } >
in let union = constructors Union
in { `Fn::Select` =
[ union.Left 0, union.Right { `Fn::GetAZs` = { Ref = "AWS::Region" } } ]
}
$ dhall-to-json <<< './example.dhall'
{"Fn::Select":[0,{"Fn::GetAZs":{"Ref":"AWS::Region"}}]}
@Gabriel439 Thanks. This allows me to remove some explicit Haskell already.
The problem is that the dhall type allows me to flip the first and the 2nd element around without violating the type check. Ideally I was able to specify both fields with their different types explicitly?
@mbj: You can wrap it in a function that enforces that invariant, like this:
-- example.dhall
let Union = < Left : Natural | Right : { `Fn::GetAZs` : { Ref : Text } } >
in let union = constructors Union
in let select =
λ(x : Natural)
→ λ(y : { `Fn::GetAZs` : { Ref : Text } })
→ { `Fn::Select` = [ union.Left x, union.Right y ] }
in select 0 { `Fn::GetAZs` = { Ref = "AWS::Region" } }
@Gabriel439 I like that, thank you.
I'll close this issue for now.
You're welcome! 🙂
While trying to encode to the following JSON structure I end up with the need to encode a JSON heterogenous array:
This is part of the Cloudformation intrinsic function syntax. See the reference here: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html
It asks for a 2 element array where the first item is a JSON number and the 2nd is a array of arbitrary JSON values.
Currently, and please correct me: There is no dhall value possible that
dhall-json
would generate this two element JSON array?Assuming the above question indeed gets answered with: No. I see two options to move on:
dhall-json
detects on conversion to JSONAnother approach
Context:
The JSON syntax allows to specify a lot of "odd" data structures. There may be target schemas that require explicit
null
values, or other structures we cannot easily find a dhall equivalent for. Adding special cases todhall-json
may be the wrong approach to handle them all. Also in many cases the special case may be "too special" to warrant another addition todhall-json
.So what if
dhall-json
(at the dhall language level!) came with an implementation of a JSON AST? Types shipped with adhall-json
specific prelude thedhall-json
Haskell implementation maps directly to aesonValue
?The nice benefit of this approach is that authors like me can keep their dhall values as compact as possible, not infecting them with JSON specific structure "early on" and only in the very last step can write some still dhall level conversion functions to that said AST.
I think this approach can likely eliminate the need to drop down to custom Haskell in many cases.
For now I'll go ahead and implement my own cloudformation specific special cases. Still I'd love to get critical feedback on this idea.