【发布时间】:2019-11-22 21:12:57
【问题描述】:
我正在学习 Scala,我试图创建一个类型类来解决“每个动物都吃食物,但食物的类型取决于动物”的问题。我有一个带有上下文边界的 Eats 类型类:
trait Eats[A <: Animal, B <: Edible]
object Eats {
def apply[A, B]: Eats[A, B] = new Eats[A, B] {}
}
Animal 和 Edible 都是抽象类。 (简化的)Animal 界面看起来像这样
abstract class Animal {
type This // concrete type
def eat[A <: Edible](food: A)(implicit e: Eats[This, B]) = // ...
}
我的目标是仅在给定类型的动物和食物存在实例(范围内的隐式值)时才允许以 animal.eat(food) 的形式调用。为此,我创建了一个 EatingBehaviour 对象,它基本上包含所有关系的实例。例如。声明奶牛吃草我添加了一行
implicit val cowEatsGrass = Eats[Cow, Grass]
类似于您在 Haskell 中编写 instance Eats Cow Grass 的方式。但是,现在我需要为 Animal 类的所有子类型指定抽象类型 This,以便 Animal 接口中的签名工作:
class Cow extends Animal { type This = Cow }
这是多余的。
因此我的问题:我能否以某种方式在 Animal 中初始化类型变量 This,以便它始终反映具体类型,类似于我如何使用 @987654336 请求动态类型@?
【问题讨论】:
-
您需要
eat成为Animal的方法还是可以在另一个对象上?
标签: scala types typeclass implicit type-members