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

Support template haskell for multiple datatypes #1664

Merged
merged 1 commit into from Feb 10, 2020
Merged

Conversation

@Gabriel439
Copy link
Collaborator

Gabriel439 commented Feb 9, 2020

Inspired by this discussion: https://discourse.dhall-lang.org/t/makehaskelltypefromunion-and-fields-with-sum-types/150

This adds a new makeHaskellTypes utility which can generate multiple
types which can refer to each other. The trick is that the type
compares nested Dhall types against top-level ones and replaces them
with Haskell datatype references when the types are judgmentally
equivalent.

Inspired by this discussion: https://discourse.dhall-lang.org/t/makehaskelltypefromunion-and-fields-with-sum-types/150

This adds a new `makeHaskellTypes` utility which can generate multiple
types which can refer to each other.  The trick is that the type
compares nested Dhall types against top-level ones and replaces them
with Haskell datatype references when the types are judgmentally
equivalent.
@srid

This comment has been minimized.

Copy link
Contributor

srid commented Feb 10, 2020

@Gabriel439 I'm using this to see how it works in my code base. makeHaskellTypes successfully generates Haskell types for the 3 Dhall types (see the PR linked above).

However, as briefly mentioned in Discourse, the only problematic parts are newtypes ... specifically newtypes over non-Dhall types.

The original types use two newtypes -- Markdown and Day -- which are both over a Haskell library type. Originally the builtin type Text is used in the Dhall type def, which are loaded using the string parser in their FromDhall instances, which in turn converts the Text to Markdown or Day (using MMark.parse and parseTimeOrError respectively).

I also think needing to define parallel types that differ only in some fields using newtypes beats the point of generating the original type using TH. I don't know what a good solution to this would be. We could hack the arguments to the TH function to specify custom types for record fields, but this won't map well to sum type constructor arguments. Unfortunately newtypes are unavoidable if we are to parse some well-known types like dates.

@Gabriel439

This comment has been minimized.

Copy link
Collaborator Author

Gabriel439 commented Feb 10, 2020

@srid: This is a pretty common issue for IDLs in general (e.g. protocol buffers, thrift, etc.). Usually the generated code doesn't exactly match what you want and you have to perform some additional conversions to the actual types you want to use or settle for the default type

Copy link
Collaborator

sjakobi left a comment

Looks great!

@Gabriel439 Gabriel439 merged commit fe7ebea into master Feb 10, 2020
4 checks passed
4 checks passed
Summary 1 rule matches and 1 potential rule
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
hydra Hydra build #51334 of dhall-haskell:1664:dhall
Details
@Gabriel439 Gabriel439 deleted the gabriel/th_multiple branch Feb 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

3 participants
You can’t perform that action at this time.