{"id":13531301,"url":"https://github.com/dhall-lang/dhall-to-cabal","last_synced_at":"2025-12-11T23:18:29.801Z","repository":{"id":51030254,"uuid":"118008660","full_name":"dhall-lang/dhall-to-cabal","owner":"dhall-lang","description":"Compile Dhall expressions to Cabal files","archived":false,"fork":false,"pushed_at":"2022-12-26T20:23:22.000Z","size":588,"stargazers_count":101,"open_issues_count":22,"forks_count":17,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-07-08T04:59:42.603Z","etag":null,"topics":["cabal","dhall","haskell","packaging"],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dhall-lang.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-18T16:32:29.000Z","updated_at":"2025-01-09T14:34:32.000Z","dependencies_parsed_at":"2023-01-31T01:15:16.194Z","dependency_job_id":null,"html_url":"https://github.com/dhall-lang/dhall-to-cabal","commit_stats":null,"previous_names":["ocharles/dhall-to-cabal"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/dhall-lang/dhall-to-cabal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhall-lang%2Fdhall-to-cabal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhall-lang%2Fdhall-to-cabal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhall-lang%2Fdhall-to-cabal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhall-lang%2Fdhall-to-cabal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dhall-lang","download_url":"https://codeload.github.com/dhall-lang/dhall-to-cabal/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhall-lang%2Fdhall-to-cabal/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265009644,"owners_count":23697216,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cabal","dhall","haskell","packaging"],"created_at":"2024-08-01T07:01:01.848Z","updated_at":"2025-12-11T23:18:29.747Z","avatar_url":"https://github.com/dhall-lang.png","language":"Haskell","funding_links":[],"categories":["Output Formats","Haskell"],"sub_categories":[],"readme":"# `dhall-to-cabal` - generate Cabal files from Dhall expression\n\n`dhall-to-cabal` takes [Dhall](https://dhall-lang.org) expressions and compiles\nthem into [Cabal](https://www.haskell.org/cabal/) files. All of the features of\nDhall are supported, such as `let` bindings and imports, and all features of\nCabal are supported (including conditional stanzas).\n\n## Getting Started\n\nTo get started with `dhall-to-cabal`, first install the `dhall-to-cabal`\nexecutable. This can be done using cabal:\n\n```sh\ncabal install dhall-to-cabal\n```\n\n(You may need to run `cabal update` first).\n\nNext, write the Dhall expression that you would like to compile to a Cabal file.\nFor some example Dhall files, see\n\n* [`dhall-to-cabal.dhall`](https://github.com/ocharles/dhall-to-cabal/blob/1.0-RC1/dhall-to-cabal.dhall) -\n  the Dhall expression building the Cabal file of this very project. \n* [`lens.dhall`](https://github.com/ocharles/dhall-to-cabal/blob/1.0-RC1/golden-tests/lens.dhall) - \n  a subset of the `lens` library's Cabal file, translated to Dhall.\n* [`str-sig.dhall`](https://github.com/ocharles/dhall-to-cabal/blob/1.0-RC1/golden-tests/str-sig.dhall) -\n  an example of using Backpack.\n\nTo see the full schema supported by `dhall-to-cabal`, you can run\n`dhall-to-cabal --print-type`. (In the future, we will have more human-ready\ndocumentation - we'd love your help here!)\n\nOnce you have your Dhall file ready, point `dhall-to-cabal` at it:\n\n``` shell\ndhall-to-cabal input.dhall\n```\n\n(Replace the name `input.dhall` with your actual input file).\n\nThat's it! `dhall-to-cabal` does the rest - it will figure out what\nthe `.cabal` file should be called, and write it out next to the\ninput.\n\nIf you'd rather put the file somewhere else, have a look at\n`dhall-to-cabal --help` and use one of the `--output-*` options.\n\n### cabal-to-dhall\n\nGood news! `dhall-to-cabal` is currently running a two-for-one deal! By\ninstalling `dhall-to-cabal` we'll throw in the `cabal-to-dhall` executable\n*absolutely free*! `cabal-to-dhall` does the reverse of `dhall-to-cabal` -\ntaking `.cabal` files and transforming them into appropriate Dhall expressions.\nThis can be a great way to get started with `dhall-to-cabal`.\n\n## The Details\n\nAs the name suggests, `dhall-to-cabal` takes\n[Dhall](https://dhall-lang.org) expressions and compiles them into\n[Cabal](https://www.haskell.org/cabal/) files. There are two moving pieces here,\nso let's break it down.\n\n## Dhall?\n\nDhall is a relatively new language [started by Gabriel\nGonzales](http://www.haskellforall.com/2016/12/dhall-non-turing-complete-configuration.html)\nin late 2016. The language bills itself as \"a configuration language guaranteed\nto terminate\". In terms of features, we have a language with:\n\n* Let bindings and lambdas for abstraction\n* Built-in support for primitive types - naturals, doubles, integers, text, booleans\n* Composite types - optional values (like `Maybe` in Haskell), lists and records\n* An import mechanism to import expressions from foreign sources (local files or\n  over HTTP)\n* A type system to type check all of the above\n* [Standards](https://github.com/dhall-lang/dhall-lang/blob/master/standard/semantics.md)\n  to promote adoption in multiple languages.\n\nTo give you an example of a Dhall expression, let's jump straight in and see an\nexample of a Dhall expression that can be used with `dhall-to-cabal`:\n\n```dhall\nlet GitHub-project =\n      https://raw.githubusercontent.com/dhall-lang/dhall-to-cabal/1.3.4.0/dhall/utils/GitHub-project.dhall\n\nlet prelude =\n      https://raw.githubusercontent.com/dhall-lang/dhall-to-cabal/1.3.4.0/dhall/prelude.dhall\n\nin    GitHub-project { owner = \"ocharles\", repo = \"example\" }\n    ⫽ { version =\n          prelude.v \"1.0.0\"\n      , library =\n          prelude.unconditional.library\n          (   prelude.defaults.MainLibrary\n            ⫽ { build-depends =\n                  [ { package =\n                        \"base\"\n                    , bounds =\n                        prelude.majorBoundVersion (prelude.v \"4\")\n                    }\n                  ]\n              , exposed-modules =\n                  [ \"Hello.World\" ]\n              }\n          )\n      }\n```\n\nWe can see quite a few features in use here. Ignoring what this file actually\ndoes (for now), let's focus on the language features.\n\nAt the start of we can see a few `let` bindings whose values themselves are\nimports over HTTP. Finally, we get into the body of the expression which is\nformed from two parts - function application of `GitHub-project` which is given\na record as argument (with `owner` and `repo` `Text` fields), and another larger\nrecord. The result of `GitHub-project` and the `library`-containing record are\nthen \"merged\" together using the `⫽` operator. In this case, you can think of\nthis as overriding or extending the result of `GitHub-project` with an extra\n`library` field.\n\nIt's OK if you don't follow all of the above - my goal is to simply get you\nfamiliar with what a Dhall expression would look like. The Dhall language itself\nhas a [much more detailed\ntutorial](https://hackage.haskell.org/package/dhall-1.9.1/docs/Dhall-Tutorial.html)\nand [other documentation](https://github.com/dhall-lang/dhall-lang/wiki).\n\n## Cabal?\n\nCabal is something that you might already be familiar with, but if you're not, Cabal is:\n\n\u003e a system for building and packaging Haskell libraries and programs. It defines\n\u003e a common interface for package authors and distributors to easily build their\n\u003e applications in a portable way. Cabal is part of a larger infrastructure for\n\u003e distributing, organizing, and cataloging Haskell libraries and programs.\n\n(taken from [the Cabal homepage](https://www.haskell.org/cabal/)).\n\nAlmost all Haskell libraries are built using some parts of the Cabal system.\n\nFor the purposes of this project, we're interested in `.cabal` files themselves.\nCabal is a build-system, but it's also a domain specific language for *driving*\nthis build system.\n\nA small example Cabal file is\n\n```cabal\ncabal-version: 2.2\nname: example\nversion: 1.0.0\nhomepage: https://github.com/ocharles/example\nbug-reports: https://github.com/ocharles/example/issues\n\nsource-repository head\n    type: git\n    location: https://github.com/ocharles/example\n\nlibrary\n    exposed-modules:\n        Hello.World\n    build-depends:\n        base ^\u003e=4\n```\n\nIn this, we see some leading metadata about the Haskell package itself - the\nname of the package, its homepage and its license, and so on. Towards the end of\nthe file, we add a library component to the package. To build this library, we\ndepend on the `base` library (which contains the standard Haskell prelude) and\nwill expose the `Hello.World` module as our API.\n\n## dhall-to-cabal?\n\n`dhall-to-cabal` tries to bridge the gap between these two separate worlds by\nallowing users to drive the Cabal build system via Dhall expressions. If you\nhadn't noticed by now, you've already seen an input Dhall-to-Cabal expression,\nand you've also already seen the corresponding output!\n\n### Getting Started\n\nYou can get `dhall-to-cabal` [from\nHackage](https://hackage.haskell.org/package/dhall-to-cabal). For usage, run\n`dhall-to-cabal --help`. For some example Dhall expressions, see\n[`dhall-to-cabal.dhall`](https://github.com/ocharles/dhall-to-cabal/blob/1.0-RC1/dhall-to-cabal.dhall),\n[`lens.dhall`](https://github.com/ocharles/dhall-to-cabal/blob/1.0-RC1/golden-tests/lens.dhall)\nor\n[`str-sig.dhall`](https://github.com/ocharles/dhall-to-cabal/blob/1.0-RC1/golden-tests/str-sig.dhall).\nThese are all fairly big expressions to test the project itself... if you have a\nsimpler example that you think would act as good reference, that would make a\ngreat starting pull request!\n\n## Why?\n\nI wrote dhall-to-cabal for a few reasons. Firstly, let's start with the\nself-centered arguments:\n\n* I wanted to learn more about Dhall. Specifically, I wanted to get comfortable\n  with what I could do with the language, and how I could use it to solve\n  problems in a specific domain. I'm beginning to view it in the same light as I\n  would view [Lua](https://www.lua.org/) and would like to explore that more in\n  the future.\n\n* I wanted to help drive Dhall development, as before even getting stuck in I\n  believed it was a worth-while project. I think even the 1.0 release of\n  dhall-to-cabal has been of value - I've reported 18 issues (14 of which have\n  been closed, usually fixed!), and I think we're starting to have discussions\n  in Dhall that are helping drive the overall project forward.\n\n* [It was requested](https://github.com/dhall-lang/dhall-haskell/issues/78)\n  and I agree that it sounds like a project that should exist. The existence of\n  [`hpack-dhall`](https://github.com/sol/hpack-dhall) strengthens this argument.\n\nThese are enough for me to justify the work, but it doesn't necessarily imply\nthat the project is of value. However, I think there *is* some value in this\nproject.\n\n* Cabal (the language) is limited in expressivity. We only just got `common`\n  blocks that allow us to abstract *some* details out and share them between\n  stanzas, but they still don't even come close to the amount of expressivity\n  given with `let`, function abstraction and remote imports.\n\n* What a Cabal file \"is\" has historically been somewhat vague. Thankfully, there\n  has been a recent effort to start moving stuff into [an excellent Read the\n  Docs user's guide](https://www.haskell.org/cabal/users-guide/), but this is\n  still incomplete. A search for \"backpack\" and \"mixins\" returns no results,\n  though these *are* valid keywords in the library stanza.\n  \n  Dhall-to-Cabal does not suffer from the mismatch between documentation and\n  internal implementation because as Dhall is type-checked we *always* have a\n  canonical type of Cabal packages.\n\n* Cabal is one-size fits all, but is that actually true? Some languages require\n  special treatment, and the best we can do right now is to document that in the\n  README. Take the [`network`\n  library](https://hackage.haskell.org/package/network):\n  \n  \u003e In network-2.6 the Network.URI module was split off into its own package, network-uri-2.6. If you're using the Network.URI module you can automatically get it from the right package by adding this to your .cabal file:\n\n  That's right - people have to copy and paste some code. I couldn't imagine\n  requiring people do that in actual Haskell code, so why do we treat Cabal\n  files differently?\n  \n  In Dhall-to-Cabal, we can hide away the fiddly details in a separate Dhall\n  expression, and provide it as something that users can import.\n  \n* We can go beyond Cabal files. If Cabal is a domain specific language for\n  building Haskell projects, what does a domain specific language for building\n  Haskell *web applications* look like? Does the separate of `library`,\n  `executable`, and `test-suite` make sense here? Maybe we'd rather:\n  \n  ```haskell\n  servant-project {\n    api-route = \"My.API.Route\"\n    server = \"My.API.Server\"\n    models = [ \"My.API.Pancake\", \"My.API.Waffle\" ]\n  }\n  ```\n  \n  and have this take care of some other details.\n  \n  I don't know what this bit of the future looks like, but I think there is\n  certainly something there.\n\n  We can also see the desire to have this import/reuse functionality in core\n  libraries. The [`network`](https://hackage.haskell.org/package/network)\n  library opens with a stanza about how you have to add the library to your\n  cabal file which is totally non-standard. Just give me an expression to\n  import, and then I don't have to worry about the details!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdhall-lang%2Fdhall-to-cabal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdhall-lang%2Fdhall-to-cabal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdhall-lang%2Fdhall-to-cabal/lists"}