Labra Labra - 3 months ago 4
Scala Question

Using abstract types with type classes in Scala

I want to use an abstract type

Value
constrained to belong to the type class
Show
from cats.

My first attempt would be something like:

package examples
import cats._
import cats.data._
import cats.implicits._

class UsingShow1 {
type Value <: Show[Value] // Not sure if this declaration is right

def showValues(vs: List[Value]): String =
vs.map(implicitly[Show[Value]].show(_)).mkString // Error line

}


But the compiler doesn't find the implicit parameter
Show[Value]
.

I know that I can define the previous example as:

class UsingShow2[Value: Show] {
def showValues(vs: List[Value]): String =
vs.map(implicitly[Show[Value]].show(_)).mkString
}


However, I wanted to know if it is possible to use abstract types instead of type parameters.

Answer

Simply add an implicit parameter of type Show[Value], at use site, as usual:

class UsingShow1 {
  type Value
  def showValues(values: List[Value])(implicit showValue: Show[Value]): String =
    values.map(showValue.show).mkString
}

But a more direct translation of your UsingShow2 class would be the following:

class UsingShow1 {
  type Value
  implicit def showValue: Show[Value]

  def showValues(values: List[Value]): String =
    values.map(showValue.show).mkString
}

Basically, since you’ve traded your type parameter Value for an abstract type member, you also have to trade your implicit parameter for an implicit abstract member (showValue in my example).

Comments