gpt4 book ai didi

Scala:要求抽象类的伴随对象的成员

转载 作者:行者123 更新时间:2023-12-04 02:04:06 25 4
gpt4 key购买 nike

我想创建一个抽象类,并能够向其中添加成员以引用实现类的伴随对象的属性。像这样的东西(Scala 伪代码):

abstract class Fruit(cultivar: String) {
// How do I reference the implementing class's companion object here?
def isTastyCultivar(): Boolean = Fruit.tastyCultivars.contains(cultivar)
}

// how do I implement what I am thinking of as "the abstract companion object"
abstract object Fruit {
val tastyCultivars: Set[String] // must be implemented
// by the concrete object
}

class Apple(cultivar: String) extends Fruit(cultivar) {

}

object Apple extends Fruit{ // presumably this is not correct;
// it needs to extend the FruitObject
// or whatever it is
val tastyCultivars: Set[String] = Set("Red Delicious", "Granny Smith")
}

class Tomato(cultivar: String) extends Fruit(cultivar) {

}

object Tomato extends Fruit{
val tastyCultivars = Set("Roma")
}

val a1 = new Apple("Red Delicious")
val a2 = new Apple("Honeycrisp")

a1.isTastyCultivar() // should return true
a2.isTastyCultivar() // should return false

val t1 = new Tomato("Roma")
val t2 = new Tomato("San Marzano")

t1.isTastyCultivar() // should return true
t2.isTastyCultivar() // should return false

抱歉,如果这是一个愚蠢的问题,或者如果之前有人问过(我对如何表达这个问题没有信心,所以我无法轻松搜索它)。提前致谢!

最佳答案

一个可能的解决方案是使用 type class pattern .我们通过 ADT 拥有我们的领域模型(或代数):

sealed trait Fruit
case class Apple() extends Fruit
case class Orange() extends Fruit

我们有我们的类型类,它定义了我们想要提供的结构:

trait TastyCultivarSupplier[T <: Fruit] {
def tastyCultivars: Set[String]
}

现在,每个拥有美味品种的类型都需要实现类型类才能提供它们。一种可能的方法是在伴随对象中实现类型类:

object Apple {
implicit def appleTastyCultivars = new TastyCultivarSupplier[Apple] {
override def tastyCultivars: Set[String] = Set("Yummy stuff")
}
}

在消费者或想要获得美味品种的类型中,我们需要一个隐含的证据来证明 TastyCultivarSupplier:

class TastyCultivarConsumer {
def isTasty[T: TastyCultivarSupplier](name: String): Boolean =
implicitly[TastyCultivarSupplier[T]].tastyCultivars.contains(name)
}

isTasty 被调用时,它需要在范围内有一个供应商,否则会发生编译时错误:

def main(args: Array[String]): Unit = {
println(new TastyCultivarConsumer().isTasty("Yummy stuff"))
}

会给我们:

Error:(33, 48) could not find implicit value for evidence parameter
of type TastyCultivarSupplier[T]
println(new TastyCultivarConsumer().isTasty("Yummy stuff"))

为了解决这个问题,我们导入我们想要的供应商:

def main(args: Array[String]): Unit = {
import Apple._
println(new TastyCultivarConsumer().isTasty("Yummy stuff"))
}

现在我们的代码可以编译了。请注意,实现者不会被迫在伴随对象中编写证据,他可以在任何他想要的地方自由地这样做,只要它在编译器可以找到的范围内。

关于Scala:要求抽象类的伴随对象的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44913315/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com