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

1

0

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

Propinquity answered 16/6, 2020 at 1:1 Comment(0)
D
2

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?

Drupe answered 16/6, 2020 at 1:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.