【问题标题】:Scala implicit def returning A with BScala 隐式 def 返回 A 和 B
【发布时间】:2019-03-02 16:27:09
【问题描述】:

我一直在为此苦恼,我不知道是否有办法正确地做到这一点。 我觉得我知道问题出在哪里,但不知道如何解决。

我有一个方法:

implicit def combineAlg[A: Alg, B: Alg]: Alg[A with B] = ...

如果我明确地调用它,它可以正常工作,但它永远不会被正确地暗示。

// works
implicit val comb: Alg[A with B] = combineAlg[A, B]

// doesn't work
implicit val comb: Alg[A with B] = implicitly[Alg[A with B]]

通过我使用 -Xlog-implicits 进行的调试,我相信它调用了 combineAlg[A with B, Nothing]

我正在寻找一种方法来做类似的事情:

implicit def combineExpAlg[AB, A >: AB, B >: AB]

implicit def combineExpAlg[AB, A, B](implicit ev1: AB <:< A, ev2: AB <:< B)

这样它就知道它需要拆分“with”,但两者都没有帮助。

不确定是否有办法做到这一点,实际上这是我在 Scala 中为“对象代数”做的一个实验,我正在尝试看看如何删除样板。

如果有解决方案,那就太棒了。 一个 dotty 解决方案也是可以接受的,因为我也在那里实现它,看看是否有一些新功能使它更简单。

如果需要更多信息,您可以查看存储库here 我想要改变的是algebra.combineExpAlg。 看起来它正在工作,因为我在 algebra.interpreters.package 中定义了特定的隐式,专门拼出每个解释器对,这就是我想要概括的内容。

【问题讨论】:

    标签: scala generics typeclass implicit dotty


    【解决方案1】:

    以下代码编译:

      trait Alg[T]
    
      trait LowPriorityAlg {
        implicit def bAlg: Alg[B0] =  ???
      }
      object Alg extends LowPriorityAlg {
        implicit def aAlg: Alg[A0] =  ???
        implicit def combineAlg[AB, A: Alg, B: Alg](implicit ev1: AB <:< A, ev2: AB <:< B): Alg[AB] = ???    
      }
    
      trait A0
      trait B0
    
      val comb: Alg[A0 with B0] = Alg.combineAlg[A0 with B0, A0, B0]
    
      val comb1: Alg[A0 with B0] = implicitly[Alg[A0 with B0]]
    

    【讨论】:

    • 这很奇怪,给 A0 或 B0 一个较低的优先级似乎可以做到这一点,你甚至可以交换它们,它仍然有效,但是给它们相同的优先级会导致问题。
    • 没那么奇怪。如果A0B0 具有相同的优先级,那么对于scalacOptions += "-Xlog-implicits",我们会收到警告Information: App.this.Alg.combineAlg is not a valid implicit value for App.Alg[App.A0 with App.B0] because: hasMatchingSymbol reported error: ambiguous implicit values: both method aAlg in object Alg of type =&gt; App.Alg[App.A0] and method bAlg in object Alg of type =&gt; App.Alg[App.B0] match expected type App.Alg[A]
    猜你喜欢
    • 1970-01-01
    • 2011-03-26
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多