如何在 Dhall 中编码多深度的规则树?

How can I encode a rule tree of multiple depths in Dhall?

我正在尝试将一些容易出错的 YAML 移到 Dhall 中,以简化一些系统配置。我有一棵看起来像的树:

composite:
  condition: And
  rules:
    - composite:
        condition: And
        rules:
          - leaf:
              static: true
          - leaf:
              exists: some-property-to-lookup
    - composite:
        condition: Or
        rules:
          - composite:
              condition: And
              rules:
                - leaf:
                    static: true
                - leaf:
                    exists: some-property-to-lookup         

我正在尝试在 Dhall 中对其进行编码,但我似乎无法向编译器提供正确的信息。我最近的尝试看起来像:

let Field
    : Type
    = < B : { static : Bool } | S : { exists : Text } >

let Condition
    : Type
    = < And | Or | Not >

let Node
    : Type
    = ∀(Node : Type) →
      ∀(Leaf : { leaf : Field }) →
      ∀(Branch : { composite : { condition : Condition, rules : List Node } }) →
        Node

let example
    : Node
    = ∀(Node : Type) →
      ∀(Leaf : { leaf : Field }) →
      ∀(Branch : { composite : { condition : Condition, rules : List Node } }) →
        Branch
          { composite =
            { condition = Condition.And
            , rules =
              [ Branch
                  { composite =
                    { condition = Condition.And
                    , rules = [ Leaf { leaf = Field.S { exists = "hi" } } ]
                    }
                  }
              , Branch
                  { composite =
                    { condition = Condition.Or
                    , rules = [ Leaf { leaf = Field.S { static = true } } ]
                    }
                  }
              , Branch
                  { composite =
                    { condition = Condition.And
                    , rules =
                      [ Branch
                          { composite =
                            { condition = Condition.And
                            , rules =
                              [ Leaf { leaf = Field.S { exists = "hi" } } ]
                            }
                          }
                      , Branch
                          { composite =
                            { condition = Condition.Or
                            , rules =
                              [ Leaf { leaf = Field.S { static = true } } ]
                            }
                          }
                      ]
                    }
                  }
              ]
            }
          }

in  example

但我得到 Error: Not a function。任何指针将不胜感激。

我也尝试过使用 Graph 模块,但我似乎无法将其直接转换为 YAML。

这个有效:

let Field
    : Type
    = < B : { static : Bool } | S : { exists : Text } >

let Condition
    : Type
    = < And | Or | Not >

let Node
    : Type
    = ∀(Node : Type) →
      ∀(Leaf : { leaf : Field } → Node) →
      ∀(Branch : { composite : { condition : Condition, rules : List Node } } → Node) →
        Node

let example
    : Node
    = λ(Node : Type) →
      λ(Leaf : { leaf : Field } → Node) →
      λ(Branch : { composite : { condition : Condition, rules : List Node } } → Node) →
        Branch
          { composite =
            { condition = Condition.And
            , rules =
              [ Branch
                  { composite =
                    { condition = Condition.And
                    , rules = [ Leaf { leaf = Field.S { exists = "hi" } } ]
                    }
                  }
              , Branch
                  { composite =
                    { condition = Condition.Or
                    , rules = [ Leaf { leaf = Field.B { static = True } } ]
                    }
                  }
              , Branch
                  { composite =
                    { condition = Condition.And
                    , rules =
                      [ Branch
                          { composite =
                            { condition = Condition.And
                            , rules =
                              [ Leaf { leaf = Field.S { exists = "hi" } } ]
                            }
                          }
                      , Branch
                          { composite =
                            { condition = Condition.Or
                            , rules =
                              [ Leaf { leaf = Field.B { static = True } } ]
                            }
                          }
                      ]
                    }
                  }
              ]
            }
          }

in  example

这里是两者之间的diff

12,13c12,13
<       ∀(Leaf : { leaf : Field }) →
<       ∀(Branch : { composite : { condition : Condition, rules : List Node } }) →
---
>       ∀(Leaf : { leaf : Field } → Node) →
>       ∀(Branch : { composite : { condition : Condition, rules : List Node } } → Node) →
18,20c18,20
<     = ∀(Node : Type) →
<       ∀(Leaf : { leaf : Field }) →
<       ∀(Branch : { composite : { condition : Condition, rules : List Node } }) →
---
>     = λ(Node : Type) →
>       λ(Leaf : { leaf : Field } → Node) →
>       λ(Branch : { composite : { condition : Condition, rules : List Node } } → Node) →
34c34
<                     , rules = [ Leaf { leaf = Field.S { static = true } } ]
---
>                     , rules = [ Leaf { leaf = Field.B { static = True } } ]
52c52
<                               [ Leaf { leaf = Field.S { static = true } } ]
---
>                               [ Leaf { leaf = Field.B { static = True } } ]