如何验证配置与dhall的内部一致性?

如何验证配置与dhall的内部一致性?,dhall,Dhall,我将从一个激励性的配置示例开始,该配置几乎代表一个特使代理配置:) 规则是,必须定义名称集群列表才能在配置的路由部分中使用。如果仔细观察,此配置将无法加载,因为bodhi_web不是bodhi web。我该如何在Dhall中对其进行编码 一方面,我可以在let绑定中将clusters作为一个列表,这会有所帮助,但没有什么能强迫我使用绑定,实际上我想将clusters作为cluster:字段的一个求和类型?依赖类型在这方面能帮我吗(例如,我记得在purescript中做过类似的事情,它对依赖类型编

我将从一个激励性的配置示例开始,该配置几乎代表一个特使代理配置:)

规则是,必须定义名称
集群
列表才能在配置的
路由
部分中使用。如果仔细观察,此配置将无法加载,因为
bodhi_web
不是
bodhi web
。我该如何在Dhall中对其进行编码

一方面,我可以在let绑定中将
clusters
作为一个列表,这会有所帮助,但没有什么能强迫我使用绑定,实际上我想将
clusters
作为
cluster:
字段的一个求和类型?依赖类型在这方面能帮我吗(例如,我记得在purescript中做过类似的事情,它对依赖类型编程的能力有限)

或者我应该创建一个构造函数/验证器函数并滥用断言来验证它吗


或者我就不该这么做?:)

我将通过编写一个实用函数来实现这一点,该函数生成正确的按构造配置

以您的示例为例,如果我们希望确保
集群
字段下的列表始终与路由列表匹配,那么我们将从
路由
字段派生
集群
字段:

let Prelude = https://prelude.dhall-lang.org/package.dhall

let Route = { match : { prefix : Text }, route : { cluster : Text } }

let toVirtualHosts =
          \(args : { name : Text, domains : List Text, routes : List Route })
      ->  { virtual_hosts =
                  args
              //  { clusters =
                      Prelude.List.map
                        Route
                        Text
                        (\(r : Route) -> r.route.cluster)
                        args.routes
                  }
          }

in  toVirtualHosts
      { name = "webxp-api_http"
      , domains = [ "*" ]
      , routes =
          [ { match = { prefix = "/static/v5.0" }
            , route = { cluster = "bodhi_static" }
            }
          , { match = { prefix = "/" }
            , route = { cluster = "bodhi_web" }
            }
          ]
      }

我的备选方案尝试很大程度上依赖于这样一个事实,即空备选方案在转换为yaml时将最终成为文本,即:
{cluster=.static}
被解释为
cluster:static

这意味着,我可以,即:

let Clusters = < bodhi_static | bodhi_web >

let Route =
      { Type = { match : { prefix : Text }, cluster : Clusters }
      , default = {=}
      }

let Cluster = { Type = { name : Clusters }, default = {=} }

in  { matches =
        [ Route::{ match = { prefix = "/" }, cluster = Clusters.bodhi_web }
        , Route::{
          , match = { prefix = "/static" }
          , cluster = Clusters.bodhi_static
          }
        ]
    , clusters =
        [ Cluster::{ name = Clusters.bodhi_static }
        , Cluster::{ name = Clusters.bodhi_web }
        ]
    }
let Clusters=
让路=
{Type={match:{prefix:Text},cluster:Clusters}
,默认值={=}
}
让Cluster={Type={name:Clusters},默认值={=}
在{匹配中=
[路由:{match={prefix=“/”},cluster=Clusters.bodhi_web}
,路线::{
,match={prefix=“/static”}
,cluster=Clusters.bodhi_static
}
]
,簇=
[群集::{name=Clusters.bodhi_static}
,Cluster::{name=Clusters.bodhi_web}
]
}

有点重复,但更简单的i.m.o

手动定义
,然后要求路由中使用的任何值都已出现在
中,不是更安全吗?据推测,可能有多个路由使用同一个集群,如果在路由中键入错误的集群名称,这种方法只会生成一个“臃肿”的集群列表。一方面,实际上集群的定义将包含远不止一个名称。另一方面,对于Dhall,我并不在乎是否在Dhall中重新定义集群,因为
let。。。在..
子句中可以将我保存在那里:)。。。我们将尝试使用这种方法。
$ dhall-to-yaml --file ./example.dhall
virtual_hosts:
  clusters:
  - bodhi_static
  - bodhi_web
  domains:
  - *
  name: webxp-api_http
  routes:
  - match:
      prefix: /static/v5.0
    route:
      cluster: bodhi_static
  - match:
      prefix: /
    route:
      cluster: bodhi_web
let Clusters = < bodhi_static | bodhi_web >

let Route =
      { Type = { match : { prefix : Text }, cluster : Clusters }
      , default = {=}
      }

let Cluster = { Type = { name : Clusters }, default = {=} }

in  { matches =
        [ Route::{ match = { prefix = "/" }, cluster = Clusters.bodhi_web }
        , Route::{
          , match = { prefix = "/static" }
          , cluster = Clusters.bodhi_static
          }
        ]
    , clusters =
        [ Cluster::{ name = Clusters.bodhi_static }
        , Cluster::{ name = Clusters.bodhi_web }
        ]
    }