首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >委托到更具体的上下文约束(附加隐式参数)

委托到更具体的上下文约束(附加隐式参数)
EN

Stack Overflow用户
提问于 2019-12-07 10:30:19
回答 2查看 246关注 0票数 5

我正在尝试创建一个ZIO模块的示例,它有两个实现:

  1. 与circe-yaml一起使用YAML
  2. HOCON与pureConfig的结合

我的一般界面是这样的:

代码语言:javascript
复制
trait Service[R] {
  def load[T <: Component](ref: CompRef): RIO[R, T]
}

现在,我的YAML实现如下:

代码语言:javascript
复制
def loadYaml[T <: Component: Decoder](ref: CompRef): RIO[Any, T] = {...}

Decoder是特定于实现的。

现在的问题是如何将服务实现委托给loadYaml

我尝试了以下几点:

代码语言:javascript
复制
val components: Components.Service[Any] = new Components.Service[Any] {

  implicit val decodeComponent: Decoder[Component] =
      List[Decoder[Component]](
         Decoder[DbConnection].widen,
           ...
        ).reduceLeft(_ or _)

   def load[T <: Component](ref: CompRef): RIO[Any, T] = loadYaml[T] (ref)
}

这给了我:

代码语言:javascript
复制
Error:(62, 20) could not find implicit value for evidence parameter of type io.circe.Decoder[T]
       loadYaml[T] (ref)

有办法做到这一点吗?

我在Github上创建了一个示例项目:zio-comps-模块

这里描述了这个想法:用ZIO模块实现程序与其实现的解耦

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-08 09:10:12

好吧,我找到了解决办法。我所要做的就是调整load函数:

代码语言:javascript
复制
def load[T <: Component](ref: CompRef): RIO[ComponentsEnv, T] = {
  loadConf[Component](ref).map { case c: T => c }
}

第一个loadConf类型为Component

第二次转换结果(Component)结果类型为T

这是可行的,但却给出了丑陋的警告:

代码语言:javascript
复制
[warn] /Users/mpa/dev/Github/pme123/zio-comps-module/hocon/src/pme123/zio/comps/hocon/HoconComps.scala:37:46: abstract type pattern T is unchecked since it is eliminated by erasure
[warn]       loadConf[Component](ref).map { case c: T => c }
[warn]                                              ^
[warn] /Users/mpa/dev/Github/pme123/zio-comps-module/hocon/src/pme123/zio/comps/hocon/HoconComps.scala:37:36: match may not be exhaustive.
[warn] It would fail on the following inputs: DbConnection(_, _, _, _), DbLookup(_, _, _, _), MessageBundle(_, _)
[warn]       loadConf[Component](ref).map { case c: T => c }
[warn]                                    ^
[warn] two warnings found

更新-我找到了一个消除警告的解决方案:

在第十次阅读警告unchecked since it is eliminated by erasure之后,我记得可以通过添加ClassTag作为上下文绑定来解决这个问题。

我们现在看上去

代码语言:javascript
复制
trait Service[R] {
  def load[T <: Component: ClassTag](ref: CompRef): RIO[R, T]
}
票数 3
EN

Stack Overflow用户

发布于 2019-12-09 15:02:06

如果问题在于你的特质

代码语言:javascript
复制
def load[T <: Component]

在实施过程中你需要

代码语言:javascript
复制
def loadYaml[T <: Component: Decoder]

那也许你只需要把Decoder参数化

代码语言:javascript
复制
trait Service[R, D] {
  def load[T <: Component: D](ref: CompRef): RIO[R, T]
}

如果不同类型的D之间没有关系,那么您可以将其定义为Any,然后具有被trait Service[R, +D]的特性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59225054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档