Labra Labra - 1 year ago 62
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 Source

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).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download