Search code examples
dhall

How to handle enums in dhall?


I need to type and generate a config that contains string enum values. I've managed to define the following lines. In the end I need to convert the union to a string value.

let ParameterLocation = < Query : {}
                        | Header : {}
                        | Path : {}
                        | Cookie : {}
                        >
let ParameterObject = {
                          name : Text,
                          `in` : ParameterLocation,
                          required : Bool
                      }
let locationToText = \(loc : ParameterLocation) -> merge {
       Query = \(_ : {}) -> "query",
       Header = \(_ : {}) -> "header",
       Path = \(_ : {}) -> "path",
       Cookie = \(_ : {}) -> "cookie"
    } loc
let t : ParameterObject = {
    name = "organisation_id",
    `in` = ParameterLocation.Query {=},
    required = False
 }
in t // { `in` = locationToText t.`in` }

Here the record containing the union/enum is at top so I can quite easily access it, but in the final configuration, the ParameterObject si quite deeply nested.

Is there a way

  • to "traverse" an arbitrary record structure and apply locationToText wherever it is applicable ?
  • or to feed dhall-to-json/dhall-to-yaml with printer for such value ?
  • or a better way to define my enum to achieve my goal more easily ?

Solution

  • There is a proposal to add support for union types with empty alternatives (i.e. enums) to the language up here, which will be merged in a couple of days:

    https://github.com/dhall-lang/dhall-lang/pull/438

    Once that is merged, the language will support more natural enums, like this:

    let ParameterLocation = < Query
                            | Header
                            | Path
                            | Cookie
                            >
    
    let locationToText = \(loc : ParameterLocation) -> merge {
           Query = "query",
           Header = "header",
           Path = "path",
           Cookie = "cookie"
        } loc
    
    ...
    

    Also, dhall-to-json and dhall-to-yaml will be able to exploit the new built-in support for empty alternatives to render the alternative name as a string instead of stripping the tag. This should be available in the next release of the standard (version 7.0.0) and the next version of dhall-to-json/dhall-to-yaml (1.2.8).