Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compile empty association list to object rather than list? #1559

Closed
wbadart opened this issue Nov 19, 2019 · 2 comments · Fixed by #1561
Closed

Compile empty association list to object rather than list? #1559

wbadart opened this issue Nov 19, 2019 · 2 comments · Fixed by #1561
Assignees

Comments

@wbadart
Copy link

wbadart commented Nov 19, 2019

Right now, unless --noMaps is specified, we expect dhall-to-json and dhall-to-yaml to compile values of type List { mapKey = t, mapValue = u } to objects. This works when the list is populated, but it seems that whatever process transforms non-empty association lists to objects is skipped for empty ones, so you end up with a different type in the compiled file. For example:

$ dhall-to-json --version
1.5.0

$ dhall-to-json <<< '[{ mapKey = "foo", mapValue = "bar" }]'
{
  "foo": "bar"
}

$ dhall-to-json <<< '[] : List { mapKey : Text, mapValue : Text }'
[]

Expected:

$ dhall-to-json <<< '[] : List { mapKey : Text, mapValue : Text }'
{}

If this is actually the desired behavior, please let me know! But if it is, I think it would still make sense to add this behavior as an option (maybe add a command line flag like --transformEmptyAssocs or something).

There are definitely practical applications of this new behavior. In my case, I'm compiling a docker compose configuration where I represent services and networks and such as association lists, e.g.

{ services = [
  { mapKey = "my_service"
  , mapValue = Service::
    { image = "dhallhaskell/dhall-json"
    , ports = [ "8000:80" ]
    }
  } ]
, networks = [
  { mapKey = "my_net", mapValue = Network.default } ]
}

==>

services:
  my_service:
    image: "dhallhaskell/dhall-json"
    ports: [ "8000:80" ]
networks:
  my_net:
    driver: overlay

In my case, if no, say, networks have been specified, it needs to be an object rather than a list, or docker will reject it:

networks: {}

I have a work-around using Optional, but the ergonomics are dramatically better if I can allow networks = [] : List { mapKey = Text, mapValue = Network.Type } to be empty.

@sjakobi
Copy link
Collaborator

sjakobi commented Nov 19, 2019

Thanks for the report! Looks like a regression back from 0ee6ce6.

@wbadart
Copy link
Author

wbadart commented Nov 19, 2019

Glad to hear my intuition on that behavior was on track. Thanks for the quick turnaround!

sjakobi added a commit that referenced this issue Dec 1, 2019
Fixes #1559.

This requires aeson-yaml >= 1.0.5.0 since older versions
incorrectly encode empty objects.

The raised bound also fixes #1560. A regression test is included.
@mergify mergify bot closed this as completed in #1561 Dec 1, 2019
mergify bot pushed a commit that referenced this issue Dec 1, 2019
Fixes #1559.

This requires aeson-yaml >= 1.0.5.0 since older versions
incorrectly encode empty objects.

The raised bound also fixes #1560. A regression test is included.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants