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

断了今生、忘了曾经 提交于 2021-01-29 16:42:34

问题


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
  }

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

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

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?

Thanks a lot for your opinion


回答1:


You lost type refinement. Replace

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

with

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

I guess case class Thing[X]() should be case class Thing[X](x: X). Then

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

work.

How to debug implicits: In scala 2 or 3, is it possible to debug implicit resolution process in runtime?



来源:https://stackoverflow.com/questions/62399395/in-scala-what-is-the-easiest-way-to-chain-functions-defined-with-a-type-class-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!