Home > Mobile >  Scala implicit class based on type class
Scala implicit class based on type class

Time:12-22

implicit class IntIncrement(val underlying: Int) extends AnyVal {
    def increment(): Int = underlying   1
}

This is valid and allows me to do something like 1.increment()

I want to be able to constrain a type parameter to have this .increment() method on it, so I started doing this:

trait Increment[T] {
    def increment(value: T): T
}

object Increment {
    implicit val implInt: Increment[Int] = new Increment[Int] {
        def increment(value: Int): Int = {
            value   1
        }
    }
}

def increment[T](value: T)(implicit valueIntDec: Increment[T]): T = {
    valueIntDec.increment(value)
}

issue is, this increment method only allows for increment(1) instead of 1.increment()

is there any way to create an implicit class for any T that has an implicit of Increment[T]

implicit class ImplicitIncrement[T](val underlying: implicit Increment[T]) extends AnyVal {
    def increment(): T = increment(underlying)
}

something like this ^^

CodePudding user response:

You can do that, just without AnyVal:

implicit class TIncrement[T : Increment](val underlying: T)  {
    def increment: T = implicitly[Increment[T]].increment(underlying)
}

But I am not sure I see the value in delegating to the type class here: rather than creating a type class implementation for every "incrementable" type, why not just have separate implicit classes that would just increment directly?

like

implicit class I(val v: Int) extends AnyVal { def increment = v   1 }
implicit class L(val v: Long) extends AnyVal { def increment = v   1 }
   // etc

UPDATE Actually, you can do that with type class and AnyVal too:

implicit class TIncrement[T](val underlying: T) extends AnyVal  {
    def increment(implicit inc: Increment[T]): T = inc.increment(underlying)
}
  • Related