gpt4 book ai didi

scala - 如何使用 ZIO 配置处理 ADT(密封特征)

转载 作者:行者123 更新时间:2023-12-04 15:36:14 25 4
gpt4 key购买 nike

如何使用 ZIO Conf代数数据类型手动添加配置描述 .

examples我找到了一个关于如何使用 Magnolia 处理 ADT 的示例。

手动添加配置说明时是否也可以这样做?

举个例子:

sealed trait Dance
final case class A(any: Person) extends Dance
final case class B(body: Height) extends Dance

final case class Person(name: String, age: Option[Int])
final case class Height(height: Long)

Jade 兰:

val danceConfig = description[Dance]

手动:

val danceConfig = ???

最佳答案

如您所料,它很冗长。但是有不同的方法可以做到这一点,这是一个偏好问题。

为了更好地理解,我们试图在这两个选项中都比要求的更详细一些

选项 1:

  val personConfig =
(string("name") |@| int("age").optional)(Person.apply, Person.unapply)

val heightConfig =
long("height").xmap(Height)(_.height)

val aConfig = nested("any")(personConfig).xmap(A)(_.any)
val bConfig = nested("body")(heightConfig).xmap(B)(_.body)
val cConfig = boolean("can").xmap(C)(_.can)
val dConfig = string("dance").xmap(D)(_.dance)

val danceConfig =
aConfig
.orElseEither(bConfig)
.orElseEither(cConfig)
.orElseEither(dConfig)
.xmap({
case Right(value) => value: Dance
case Left(value) =>
value match {
case Right(value) => value: Dance
case Left(value) =>
value match {
case Right(value) => value: Dance
case Left(value) => value: Dance
}
}
})({
case d @ D(_) => Right(d)
case c @ C(_) => Left(Right(c))
case b @ B(_) => Left(Left(Right(b)))
case a @ A(_) => Left(Left(Left(a)))
}
)

在写入端有点复杂,但它都是类型驱动的。

选项 2

   val personConfig =
(string("name") |@| int("age").optional)(Person.apply, Person.unapply)

val heightConfig =
long("height").xmap(Height)(_.height)

val aConfig = nested("any")(personConfig).xmap(A)(_.any)
val bConfig = nested("body")(heightConfig).xmap(B)(_.body)
val cConfig = boolean("can").xmap(C)(_.can)
val dConfig = string("dance").xmap(D)(_.dance)

val aConfigAsDance =
aConfig.xmapEither(a => Right(a: Dance))({
case a: A => Right(a)
case _ => Left("unable to write back")
})

val bConfigAsDance =
bConfig.xmapEither(a => Right(a: Dance))({
case a: B => Right(a)
case _ => Left("unsable to write back")
})

val cConfigAsDance =
cConfig.xmapEither(a => Right(a: Dance))({
case a: C => Right(a)
case _ => Left("unsable to write back")
})

val dConigAsDance =
dConfig.xmapEither(a => Right(a: Dance))({
case a: D => Right(a)
case _ => Left("unsable to write back")
})

val danceConfig =
aConfigAsDance.orElse(bConfigAsDance).orElse(cConfigAsDance).orElse(dConigAsDance)


您可能已经注意到,在写入部分(xmapEither 的第二个参数)我们确保它是正确的类型。示例:在 aConfigAsDance 中,假设它只能是 A 并执行 asInstanceOf 是不安全的。

有了 xmapeither,我们能够编写安全和纯净的代码,我们也遵循了它。

在未来,zio-config 会提供一些辅助函数来处理 Either。这是因为 ZIO-Config 的理念是为用户提供尽可能不那么神奇的界面,同时您仍然可以使用 zio-config-magnolia 将它们缩短到只有一行,即

val danceConfig = description[Dance]

如果您有兴趣,很高兴在 zio-config 中恢复这个示例。非常感谢这个问题,希望回答对您有所帮助。

关于scala - 如何使用 ZIO 配置处理 ADT(密封特征),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59670366/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com