【发布时间】:2017-06-29 18:11:46
【问题描述】:
我写了一个基本的代数数据类型定义如下
sealed trait Fruit {def name: String}
case class Apple(name: String) extends Fruit
case class Orange(name: String, color: String) extends Fruit
我想做的是定义一个跨 Apple 和 Orange 的通用方法。所以我决定通过 Type Class 模式来提供这个特性。
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
}
}
对于一个必要的(和不幸的)约束,我必须将水果作为 共享基本特征的有界实例 Fruit
def myCodeMethod[F <: Fruit](fruit: F, out: String) = {
import FruitManager._
FruitManager.retrievePeelColor(fruit)
}
这让我想到了以下(以某种方式预期的)异常。
could not find implicit value for evidence parameter of type my.path.to.fruit.ServingFruit[F] [error]FruitManager.retrievePeelColor(fruit)
然后,AFAIU here 和 here 类型类模式是类型独立的,也许后者不太适合我的场景。
关键是我正在努力寻找一个有价值的解决方案,将我的 ADT 与基本特征也可用的通用方法集成在一起,同时我想避免在 ADT 中提供这些方法(我会尝试保持面向 FP)并使用这样的变通方法,例如在我的类型类中添加一个额外的Fruit 转换器。
非常感谢任何帮助,谢谢。
安德烈亚
【问题讨论】:
标签: scala functional-programming typeclass algebraic-data-types