0

给定的是应用程序和容器的配置,其中一个应用程序能够拥有多个容器,一个容器能够拥有多个应用程序。我希望能够以两种方式输出它们

  • 每个应用列出容器
  • 每个容器列出应用程序

数据格式很简单,但我似乎无法找到一种方法来获得这两种表示而不重复关系。

从具有应用程序的容器开始时的示例数据

let app1 = { name = "app1" }
let app2 = { name = "app2" }

let containers = [
  { name = "container1", apps = [ app1 ] },
  { name = "container2", apps = [ app1, app2 ] }
]

{- I can easily transform this data to the following -}

[
  { app = "app1", container = "container1" },
  { app = "app1", container = "container2" },
  { app = "app2", container = "container2" }
]

{- But I cannot seem to get it into the requested format -}
[
  "app1" = [ "container1", "container2" ]
  "app2" = [ "container2" ]
]

我认为使用标识符是Text行不通的,因为没有办法使用相等的标识符来合并关联列表或类似的东西。

使用记录我可以合并这样的东西{a1 = {c1 = True}} /\ {a1 = {c2 = True}} /\ {a2 = {c2 = True}}。这将是{a1 = {c1 = True, c2 = True}, a2 = {c2 = True}}。但我一开始就无法达到这种状态,因为我无法“逆转”记录。

我不在乎我需要如何构建配置,只要我不需要重复两次关系。

4

1 回答 1

1

是的,不可能完全按照您的要求做,因为该语言不允许Text比较

我能想到的最接近的解决方案是这样的:

let Map = https://prelude.dhall-lang.org/v21.1.0/Map/Type.dhall

let List/concatMap = https://prelude.dhall-lang.org/v21.1.0/List/concatMap.dhall

let List/map = https://prelude.dhall-lang.org/v21.1.0/List/map.dhall

let startingMapping
    : Map Text (Map Text {})
    = toMap
        { container1 = toMap { app1 = {=} }
        , container2 = toMap { app1 = {=}, app2 = {=} }
        }

let desiredMapping
    : Map Text (Map Text {})
    = toMap
        { app1 = toMap { container1 = {=}, container2 = {=} }
        , app2 = toMap { container2 = {=} }
        }

let transpose
    : ∀(a : Type) → Map Text (Map Text a) → Map Text (Map Text a)
    = λ(a : Type) →
        List/concatMap
          { mapKey : Text, mapValue : Map Text a }
          { mapKey : Text, mapValue : Map Text a }
          ( λ(x : { mapKey : Text, mapValue : Map Text a }) →
              List/map
                { mapKey : Text, mapValue : a }
                { mapKey : Text, mapValue : Map Text a }
                ( λ(y : { mapKey : Text, mapValue : a }) →
                    { mapKey = y.mapKey
                    , mapValue =
                      [ { mapKey = x.mapKey, mapValue = y.mapValue } ]
                    }
                )
                x.mapValue
          )

in  assert : transpose {} startingMapping ≡ desiredMapping

但是,断言失败,并显示以下错误消息:

Error: Assertion failed

[ - { mapKey = "app1"
    , mapValue = [ { mapKey = "container1", mapValue = {=} } ]
    }
, - { mapKey = "app1"
    , mapValue = [ { mapKey = "container2", mapValue = {=} } ]
    }
, + { mapKey = "app1"
    , mapValue =
      [ { mapKey = "container1", mapValue = {=} }
      , { mapKey = "container2", mapValue = {=} }
      ]
    }
, …
]


41│     assert : transpose {} startingMapping ≡ desiredMapping

…因为结果没有app1像您要求的那样合并两个重复的键。

于 2022-01-16T21:19:09.597 回答