Conditional Restrictions

In Dhall, elements of a list must all be of the same type. There is no such restriction when using Hpack’s conditionals in a list.

Tip

Type annotations in Dhall are not required for non-empty lists when the type of element can be inferred. Empty lists always require a type annotation.

When translating a package.yaml to package.dhall we may have to add empty fields to ensure each list element has the same type. For example, in the following snippet for the stack executable, each condition doesn’t have every field. We find;

package.yaml
executables:
  stack:
    main: Main.hs
    source-dirs: src/main
    generated-other-modules:
    - Build_stack
    - Paths_stack
    ghc-options:
    - -threaded
    - -rtsopts
    dependencies:
    - stack
    when:
1    - condition: flag(static)
      ld-options:
      - -static
      - -pthread
2    - condition: ! '!(flag(disable-git-info))'
      cpp-options: -DUSE_GIT_INFO
      dependencies:
      - githash
      - optparse-simple
3    - condition: flag(hide-dependency-versions)
      cpp-options: -DHIDE_DEP_VERSIONS
    - condition: flag(supported-build)
      cpp-options: -DSUPPORTED_BUILD
1
one condition with ld-options,
2
one condition with cpp-options and dependencies,
3
two conditions with cpp-options.

To represent this in a package.dhall make sure each element has every field any of the conditions use. In this example, there are three fields and each is a List Text.

package.dhall
, executables =
    { stack =
        { main =
            "Main.hs"
        , source-dirs =
            [ "src/main" ]
        , generated-other-modules =
            [ "Build_stack", "Paths_stack" ]
        , ghc-options =
            [ "-threaded", "-rtsopts" ]
        , dependencies =
            [ "stack" ]
        , when =
            [ { condition =
                  "flag(static)"
              , cpp-options =
                  [] : List Text
              , dependencies =
                  [] : List Text
              , ld-options =
                  [ "-static", "-pthread" ]
              }
            , { condition =
                  "!(flag(disable-git-info))"
              , cpp-options =
                  [ "-DUSE_GIT_INFO" ]
              , dependencies =
                  [ "githash", "optparse-simple" ]
              , ld-options =
                  [] : List Text
              }
            , { condition =
                  "flag(hide-dependency-versions)"
              , cpp-options =
                  [ "-DHIDE_DEP_VERSIONS" ]
              , dependencies =
                  [] : List Text
              , ld-options =
                  [] : List Text
              }
            , { condition =
                  "flag(supported-build)"
              , cpp-options =
                  [ "-DSUPPORTED_BUILD" ]
              , dependencies =
                  [] : List Text
              , ld-options =
                  [] : List Text
              }
            ]
        }
    }

Another possibility is to just accept the automatic conversion of yaml-to-dhall. It takes another stance on encoding, using Optional values:

examples/stack/package-type.dhall
, executables :
    { stack :
        { dependencies : List Text
        , generated-other-modules : List Text
        , ghc-options : List Text
        , main : Text
        , source-dirs : Text
        , when :
            List
              { condition : Text
              , cpp-options : Optional Text
              , dependencies : Optional (List Text)
              , ld-options : Optional (List Text)
              }
        }