在 scala 中,链接使用类型类定义的函数以及哪个输出类型依赖于它的最简单方法是什么?



>假设定义了类Thing,并且操作+与类型类相关联:

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)

工作。

如何调试隐式:在 scala 2 或 3 中,是否可以在运行时调试隐式解析过程?

最新更新