Hi,
In my organization I’m prototyping Dhall for our configurations. I am almost done converting our old yaml spec to Dhall, but I have one more thing to fix. I have been struggling with a type error that I don’t understand. I’ve minimized it as far as I could from an example using OpenShift shown at the end. It may be about the // operator, but I don’t know. There seems to be something about the type system that I don’t understand.
The following code type-checks and works:
let Config : Type =
{ name : Text
, metadata : { labels : Text }
}
let makeConfig
: Text -> Text -> Text -> Config =
\(app : Text) -> \(name : Text) -> \(host : Text) ->
{
, name
, metadata.labels = app
}
let replaceLabels
: Text -> Config -> Config =
\(app : Text) -> \(r : Config) ->
r // { metadata.labels = app }
let generate
: Config =
let r = makeConfig "testapp" "testname" "testhost"
in replaceLabels "newapp" r
in generate
But adding an optional dummy field to Config breaks it.
let Config : Type =
{ name : Text
, metadata : { dummy : Optional Text, labels : Text }
}
let makeConfig
: Text -> Text -> Text -> Config =
\(app : Text) -> \(name : Text) -> \(host : Text) ->
{
, name
, metadata = {
, labels = app
, dummy = None Text
}
}
let replaceLabels
: Text -> Config -> Config =
\(app : Text) -> \(r : Config) ->
r // { metadata.labels = app }
let generate
: Config =
let r = makeConfig "testapp" "testname" "testhost"
in replaceLabels "newapp" r
in generate
Error:
You or the interpreter annotated this expression:
↳ λ(app : Text) → λ(r : Config) → r ⫽ { metadata.labels = app }
... with this type or kind:
↳ Text →
{ metadata : { dummy : Optional Text, labels : Text }, name : Text } →
{ metadata : { dummy : Optional Text, labels : Text }, name : Text }
... but the inferred type or kind of the expression is actually:
↳ ∀(app : Text) →
∀(r : { metadata : { dummy : Optional Text, labels : Text }, name : Text }) →
{ metadata : { labels : Text }, name : Text }
A small initial example using OpenShift is this one, but I am not sure I have minimized it correctly:
let OpenShift =
https://raw.githubusercontent.com/TristanCacqueray/dhall-openshift/master/package.dhall
sha256:a6883f73597b7dfbded7638222562c2fb0b96d30089fa8e32fa4ea43a487b32e
let makeConfig
: Text -> Text -> Text -> OpenShift.Route.Type =
\(app : Text) -> \(name : Text) -> \(host : Text) ->
OpenShift.Route::{
, metadata = OpenShift.ObjectMeta::{
, name = Some name
, labels = Some (toMap { app = app })
}
, spec = OpenShift.RouteSpec::{
, host = host
, to = OpenShift.RouteTargetReference::{
, kind = "Service"
, name = name
, weight = 100
}
}
}
let replaceLabels
: Text -> OpenShift.Route.Type -> OpenShift.Route.Type =
\(app : Text) -> \(r : OpenShift.Route.Type) ->
r // { metadata.labels = Some (toMap { app = app }) }
let generate
: OpenShift.Route.Type =
let r = makeConfig "testapp" "testname" "testhost"
in replaceLabels "newapp" r
in generate
With the type error:
You or the interpreter annotated this expression:
↳ λ(app : Text) →
λ(r : OpenShift.Route.Type) →
r ⫽ { metadata.labels = Some (toMap { app }) }
... with this type or kind:
↳ Text →
{ apiVersion : Text
, kind : Text
, metadata :
{ annotations : Optional (List { mapKey : Text, mapValue : Text })
...
}
... but the inferred type or kind of the expression is actually:
↳ ∀(app : Text) →
∀ ( r
: { apiVersion : Text
, kind : Text
, metadata :
{ annotations : Optional (List { mapKey : Text, mapValue : Text })
...
}
Can someone explain my type errors?