A little anecdote
I looked into Dhall again recently, since it seemed to me like the tooling got a lot better over the last year. I mentioned it to my colleague, who pitched me a toy challenge:
What if, for example I said:
Variable A, Values 1, 2, 3
Variable B, Values 4, 5, 6
Variable C, Values 7, 8, 9
Variable D, Values 10, 11, 12
When selecting any value for a variable, cannot select any other value for that variable
When select A1, always force add B4
When select B5, force exclude all values of variable C, and force exclude D11
When select D10, may select C9
When select D12, force select C8 and force select A1
Can it evaluate the configuration statement: “Use this module for all cases except when D11 is selected”
Now, there’s some debate about whether that’s well defined, but that’s okay! Software requirements are ill defined all the time, and type systems help us find out where the contradictions are, so I just dove in.
let A = < A1 | A2 | A3 >
let B = < B4 | B5 | B6 >
let C = < C7 | C8 | C9 >
let D = < D10 | D11 | D12 >
let Config = { a : Optional A, b : Optional B, c : Optional C, d : Optional D }
let empty = { a = None A, b = None B, c = None C, d = None D }
let examplePartial = { a = A.A1, b = None B, c = None C, d = D.D10 }
let isValid : Config -> Bool = <<validation logic>>
let fillUnderValidityConstraints : Config -> Optional Config = <<constrain partial config, or return
failure>>
in fillUnderValidityConstraints examplePartial
But now I ran into exactly this issue. Trying to compare directly of course told me that ==
was not permitted for unions. So I tried merge
:
let ruleA = {A1 = \(b: B) -> isB4, A2 = \(b:B) -> True, A3 = \(b:B) -> True}
But without wildcards I was starting down the barrel of a lot of boilerplate.
So…what should I do in a situation like this?
- Am I not taking advantage of existing language features?
- Am I using Dhall for the wrong kind of application?
- Is there a better way to “start with a strongly type representation” in this case?
- Should I wait for additional language features?