Search code examples
haskelldhall

Encoding `Map ([Text], [Text]) Text` in dhall (Haskell)


What is the best way to encode the Haskell type Map ([Text], [Text]) Text in dhall?

Attempt. It seems we can't use toMap to do this:

-- ./config.dhall

toMap { foo = "apple", bar = "banana"} : List { mapKey : Text, mapValue : Text }
x <- input auto "./config.dhall" :: IO Map Text Text

since we need the domain of the map to be of type ([Text], [Text]).


Solution

  • A Map in Dhall is just a List of mapKey/mapValue pairs:

    $ dhall <<< 'https://prelude.dhall-lang.org/v16.0.0/Map/Type'
    λ(k : Type) → λ(v : Type) → List { mapKey : k, mapValue : v }
    

    ... and the Haskell implementation encodes a 2-tuple like (a, b) as { _1 : a, _2 : b }, so the Dhall type that corresponds to your Haskell type is:

    List { mapKey : { _1 : List Text, _2 : List Text }, mapValue : Text }
    

    You're correct that you can't use toMap to build a value of that type since toMap only supports Maps with Text-valued keys. However, since a Map is just a synonym for a specific type of List you can write out the List directly (just like you would in Haskell if you were using Data.Map.fromList), like this:

    let example
        : List { mapKey : { _1 : List Text, _2 : List Text }, mapValue : Text }
        = [ { mapKey = { _1 = [ "a", "b" ], _2 = [ "c", "d" ] }, mapValue = "e" }
          , { mapKey = { _1 = [ "f" ], _2 = [ "g", "h", "i" ] }, mapValue = "j" }
          ]
    
    in  example