将不同的架构与联合值相关联的惯用方式是什么? [英] What is the dhall idiomatic way to associate different schemas to union values?

查看:70
本文介绍了将不同的架构与联合值相关联的惯用方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用Dhall类型表示Zuul-CI项目的管道系统: 管道可以使用具有不同触发事件的不同连接.

I'm trying to represent the pipeline system of the Zuul-CI project using Dhall types: a pipeline can use different connections with different trigger events.

我想提供一个默认管道,该管道可以通过以下方式为每种类型的连接设置正确的触发事件:

I'd like to provide a default pipeline that setups the correct trigger event for each type of connections in such a way that:

  ⊢ RenderPipeline CheckPipeline::{ connections = [ ConnectionTypes.GitHub ] }

  - pipeline:
    name: check
    trigger:
      github:
        action: open
        event: pull-request

  ⊢ RenderPipeline CheckPipeline::{ connections = [ ConnectionTypes.Gerrit ] }

  - pipeline:
    name: check
    trigger:
      gerrit:
        event: patchset-created

  ⊢ RenderPipeline CheckPipeline::{ connections = [ ConnectionTypes.Gerrit, ConnectionTypes.GitHub ] }

  - pipeline:
      name: check
      trigger:
        gerrit:
          event: patchset-created
        github:
          action: open
          event: pull-request

我必须对ConnectionTrigger使用Union,因为合并功能希望该值是单一类型.

I had to use an Union for ConnectionTrigger because the merge function expects the value to be a single type.

是否可以通过某种方式将GerritTrigger与ConnectionTypes.Gerrit关联,并避免在CheckPipeline定义中键入事件类型(例如,删除ConnectionTrigger.Gerrit注释)?

Is there a way to somehow associate GerritTrigger with ConnectionTypes.Gerrit and avoid typing the event type in the CheckPipeline definition (e.g. remove the ConnectionTrigger.Gerrit annotation)?

let Prelude =
      https://raw.githubusercontent.com/dhall-lang/dhall-lang/v11.1.0/Prelude/package.dhall sha256:99462c205117931c0919f155a6046aec140c70fb8876d208c7c77027ab19c2fa

let ConnectionTypes
    : Type
    = < Gerrit | GitHub >

let GerritTrigger
    : Type
    = { event : Text }

let GitHubTrigger
    : Type
    = { event : Text, action : Text }

let ConnectionTrigger
    : Type
    = < Gerrit : GerritTrigger | GitHub : GitHubTrigger >

let Pipeline
    : Type
    = { name : Text
      , trigger : { Gerrit : ConnectionTrigger, GitHub : ConnectionTrigger }
      , connections : List ConnectionTypes
      }

let CheckPipeline =
      { Type = Pipeline
      , default =
          { name = "check"
          , trigger =
              -- "Here, can this be improved so that Gerrit is not mentioned twice?"
              { Gerrit = ConnectionTrigger.Gerrit { event = "patchset-created" }
              , GitHub =
                  ConnectionTrigger.GitHub
                    { event = "pull-request", action = "open" }
              }
          }
      }

let PipelineRenderTrigger
    : Type
    = { mapKey : Text, mapValue : ConnectionTrigger }

let RenderPipeline =
        λ(pipeline : Pipeline)
      → [ { pipeline =
              { name = pipeline.name
              , trigger =
                  Prelude.List.map
                    ConnectionTypes
                    PipelineRenderTrigger
                    (   λ(connection : ConnectionTypes)
                      → { mapKey =
                            merge
                              { Gerrit = "gerrit", GitHub = "github" }
                              connection
                        , mapValue = merge pipeline.trigger connection
                        }
                    )
                    pipeline.connections
              }
          }
        ]

in  RenderPipeline CheckPipeline::{ connections = [ ConnectionTypes.GitHub ] }

先谢谢您了:)

推荐答案

是的,您可以通过在将triggers字段作为处理程序记录传递给merge之前,对其进行转换来实现此目的.这样,用户不必自己包装触发器. RenderPipeline函数为他们做到了:

Yes, you can do this by transforming the triggers field before passing it as a record of handlers to merge. That way the user doesn't have to wrap the triggers themselves; the RenderPipeline function does it for them:

let Prelude =
      https://raw.githubusercontent.com/dhall-lang/dhall-lang/v11.1.0/Prelude/package.dhall sha256:99462c205117931c0919f155a6046aec140c70fb8876d208c7c77027ab19c2fa

let ConnectionTypes
    : Type
    = < Gerrit | GitHub >

let GerritTrigger
    : Type
    = { event : Text }

let GitHubTrigger
    : Type
    = { event : Text, action : Text }

let ConnectionTrigger
    : Type
    = < Gerrit : GerritTrigger | GitHub : GitHubTrigger >

let Pipeline
    : Type
    = { name : Text
      , trigger : { Gerrit : GerritTrigger, GitHub : GitHubTrigger }
      , connections : List ConnectionTypes
      }

let CheckPipeline =
      { Type = Pipeline
      , default =
          { name = "check"
          , trigger =
              { Gerrit = { event = "patchset-created" }
              , GitHub = { event = "pull-request", action = "open" }
              }
          }
      }

let PipelineRenderTrigger
    : Type
    = { mapKey : Text, mapValue : ConnectionTrigger }

let RenderPipeline =
        λ ( pipeline
          : Pipeline
          )
      → [ { pipeline =
              { name =
                  pipeline.name
              , trigger =
                  Prelude.List.map
                    ConnectionTypes
                    PipelineRenderTrigger
                    (   λ ( connection
                          : ConnectionTypes
                          )
                      → { mapKey =
                            merge
                              { Gerrit = "gerrit", GitHub = "github" }
                              connection
                        , mapValue =
                            let {- This is the key bit!

                                   We modify the handlers before passing them to
                                   `merge` so that the user does not have to
                                -}
                                trigger =
                                  { Gerrit =
                                      ConnectionTrigger.Gerrit
                                        pipeline.trigger.Gerrit
                                  , GitHub =
                                      ConnectionTrigger.GitHub
                                        pipeline.trigger.GitHub
                                  }

                            in  merge trigger connection
                        }
                    )
                    pipeline.connections
              }
          }
        ]

in  RenderPipeline CheckPipeline::{ connections = [ ConnectionTypes.GitHub ] }

这篇关于将不同的架构与联合值相关联的惯用方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆