在 scala 中,链接使用类型 class 定义的函数的最简单方法是什么?哪种输出类型取决于它?

In scala, what is the easiest way to chain functions defined with a type class and of which output type depends on it?

假设定义了一个classThing,并且一个操作+关联了一个类型class:

  trait TypeClass[X, Y] {

    type Out
    def v: Out
  }

  object TypeClass {

    implicit def summon[X <: Int, Y <: Int]: TypeClass[X, Y] = new TypeClass[X, Y] {

      type Out = Int

      override def v: Out = 2
    }
  }

  case class Thing[X]() {

    def +[Y](that: Thing[Y])(implicit typeClass: TypeClass[X, Y]): typeClass.Out = typeClass.v
  }

现在如果我想定义一个快捷函数+2x,代表X + Y + Y。我的第一直觉是引入一个隐式参数:

    def ++[Y, Z](that: Thing[Y])(implicit t1: TypeClass[X, Y] { type Out <: Z }, t2: TypeClass[Z, Y]): t2.Out = t2.v

但是 t2 变成了一个不可能的鞋子:


    assert(Thing(1) + Thing(2) == Thing(2)) // works fine

    assert(Thing(1) ++ Thing(2) == Thing(2)) // TypeClass.scala:34: could not find implicit value for parameter t2: TypeClass.this.TypeClass[Z,Int]

我还可以使用更直观的格式:


    def +++[Y, Z](that: Thing[Y])(implicit t1: TypeClass[X, Y] { type Out <: Y }, a: Any = this + that + that): a.type =
      a

不幸的是,隐含的 t1 不能对定义结果的表达式可见:

TypeClass.scala:29: type mismatch;
 found   : a.type (with underlying type Any)
 required: AnyRef

那么最简单、最直观的定义方式是什么?

非常感谢您的意见

您丢失了类型优化。替换

implicit def summon[X <: Int, Y <: Int]: TypeClass[X, Y] = new TypeClass[X, Y] {...

implicit def summon[X <: Int, Y <: Int]: TypeClass[X, Y] {type Out = Int} = new TypeClass[X, Y] {...

我猜case class Thing[X]()应该是case class Thing[X](x: X)。那么

assert(Thing(1) + Thing(2) == 2) 
assert(Thing(1) ++ Thing(2) == 2)

工作。

如何调试隐式:In scala 2 or 3, is it possible to debug implicit resolution process in runtime?