在Scala中,最简单的方法是链接由类型类定义的函数,并且取决于哪个输出类型? [英] In scala, what is the easiest way to chain functions defined with a type class and of which output type depends on it?
问题描述
假设已定义类 Thing
,并且操作 +
与类型类相关联:
Assuming that a class Thing
is defined, and an operation +
is associated with a type 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
.我的第一个本能是引入一个隐式参数:
Now if I want to define a shortcut function +2x
, which represents X + Y + Y
. My first instinct was to introduce an implicit parameter:
def ++[Y, Z](that: Thing[Y])(implicit t1: TypeClass[X, Y] { type Out <: Z }, t2: TypeClass[Z, Y]): t2.Out = t2.v
但是随后t2变成了无法填补的鞋子:
But then t2 becomes an impossible shoe to fill:
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]
我还可以使用更直观的格式:
I could also use a more intuitive format:
def +++[Y, Z](that: Thing[Y])(implicit t1: TypeClass[X, Y] { type Out <: Y }, a: Any = this + that + that): a.type =
a
不幸的是,隐式t1无法使定义结果的表达式可见:
unfortunately implicit t1 cannot be made visible to the expression that defines the result:
TypeClass.scala:29: type mismatch;
found : a.type (with underlying type Any)
required: AnyRef
那么定义这个最简单,最直观的方法是什么?
so what is the easiest, most intuitive way to define this?
非常感谢您的意见
推荐答案
您丢失了类型优化功能.替换
You lost type refinement. Replace
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)
工作.
如何调试隐式: 查看全文