I wrote a basic Algebraic Data Type defined as follows
sealed trait Fruit {def name: String}
case class Apple(name: String) extends Fruit
case class Orange(name: String, color: String) extends Fruit
What I'd love to do is to define a common method across Apple and Orange. So I decided to offer this feature by a Type Class pattern.
sealed trait ServingFruit[T] {
def peel(fruit: T): String
}
object FruitManager {
def retrievePeelColor[T: ServingFruit](fruit: T): String =
implicitly[ServingFruit[T]].peel(fruit)
implicit object ApplePeelColor extends ServingFruit[Apple] {
def peel(fruit: Apple): String = "GREEN"
}
implicit object OrangePeelColor extends ServingFruit[Orange] {
def peel(fruit: Orange): String = fruit.color
}
}
For a necessary (and unfortunate) constraint I have to handle fruits as bounded instances of the shared base trait Fruit
def myCodeMethod[F <: Fruit](fruit: F, out: String) = {
import FruitManager._
FruitManager.retrievePeelColor(fruit)
}
And it brings me to the following (somehow expected) exception.
could not find implicit value for evidence parameter of type my.path.to.fruit.ServingFruit[F] [error]FruitManager.retrievePeelColor(fruit)
Then, AFAIU here and here Type Class Pattern is type independent and perhaps the latter is not well fitting my scenario.
The point is I'm struggling on figuring out a valuable solution to integrate my ADT with a common method available also to the base trait and - at the same time - I'd like to avoid providing the methods within the ADT (I'd try to stay FP oriented) and to use such workarounds as to add an additional Fruit
converter to my Type Class.
Any help'd be really appreciated, thank you.
Andrea