dhall-haskell icon indicating copy to clipboard operation
dhall-haskell copied to clipboard

dhall-to-json display union constructor name as parent key

Open lisael opened this issue 5 years ago • 1 comments

At the moment there are 4 ways to output JSON from a dhall Union:

let JSON/Nesting = https://prelude.dhall-lang.org/v11.1.0/JSON/Nesting

let Foo = { f : Text }
let Bar = { b : Text }

let FooBar = < Foo : Foo | Bar : Bar >

let myFoobar = FooBar.Foo { f = "myfoo" }

let FooBar/asJSON = \( f : FooBar ) ->
  merge {
    , Foo = \( foo : Foo ) -> toMap { Foo = toMap foo }
    , Bar = \( bar : Bar ) -> toMap { Bar = toMap bar }
    } f

in  {
  , default = { myfoobar = myFoobar }
  , nested_1 = { field = "foobarType", nesting = JSON/Nesting.Inline, contents = myFoobar}
  , nested_2 = { field = "foobarType", nesting = JSON/Nesting.Nested "myfoobar", contents = myFoobar}
  -- custom ( FooBar -> JSON.Object ) function
  , zcustom = FooBar/asJSON myFoobar
  }

... which gives, in YAML

default:
  myfoobar:
    f: myfoo
nested_1:
  f: myfoo
  foobarType: Foo
nested_2:
  foobarType: Foo
  myfoobar:
    f: myfoo
zcustom:
  Foo:
    f: myfoo

I did write this very custom render function a couple of times, lately, and it's mechanical enough that I think dhall-to-json could handle this with a new constructor in JSON/Nested (say AsChild, I'm not good at naming)

Example:

{ field = "ignored by dhall-to-json", nesting = JSON/Nesting.AsChild, content = FooBar.Foo { f = "hello" } }

renders as:

Foo:
  f: "hello"

The main use-case is sometimes configuration schema require mutually exclusive fields with each its own configuration.

lisael avatar Apr 22 '20 13:04 lisael

@lisael: I would be fine with something like this, except that I think a prerequisite for this is the idea that @SiriusStarr proposed in this discussion:

https://github.com/dhall-lang/dhall-haskell/issues/1383#issuecomment-541284219

... which is to start controlling this behavior via the command line instead of within the Dhall expression

For this particular change I think it's essential, since otherwise doing this properly would require either (A) introducing an ignored field field or (B) making a breaking change to Prelude.JSON.Tagged to make it more strongly typed (which is probably not advisable at this point)

Gabriella439 avatar Apr 23 '20 03:04 Gabriella439