gpt4 book ai didi

Scala Generics - ADT 中的通用提取器方法

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

我有一个类似的 ADT;

sealed trait Dimension
case object Customer extends Dimension
case object Brand extends Dimension
case object Product extends Dimension

现在这个 ADT 表示数据类中的值

case class Record(custId: Long, prodId: Int, brand: String)

如果我传入任何 Dimension 类型和 Record 的实例,我如何编写一个“维度提取器”,我就能得到它代表的值?

换句话说,我有一个 Seq[Dimension](Brand,Customer).foreach{d => println(d.extract(aRecord))}

首先想到的是做类似的事情;

trait DimExtractor[A,B] {
val extract = A => B
}

然后改变ADT:

case object Brand extends Dimension with DimExtractor[Record, String] {
val extract = (r: Record) => r.brand
}

有没有办法根据 r.brand 的返回类型隐式获取 String 类型?也许让这个成为一个def?

但这行不通,因为 Seq[Dimension with DimExtractor] 无法编译,因为它需要类型参数...但我有很多 DimExtractor[Record, ?](即,一个用于返回字符串的品牌,一个用于返回长字符串的客户等等......

我可以将其设为 DimExtractor[Record, Any]... 但这又似乎不对。

执行此操作的更好方法是什么?

最佳答案

您有 3 个 Dimension 特征的子类(对象),提取器的返回值取决于参数类型(同时考虑 ab 作为 a.method(b)method 的参数)。您可以使用依赖于路径的类型。

sealed trait Dimension {
}

trait DimExtractor[R] {
type Ret
def extract(r: R): Ret
}

case object Customer extends Dimension with DimExtractor[Record] {
type Ret = Long
def extract(r: Record): Ret = r.custId
}
case object Brand extends Dimension with DimExtractor[Record] {
type Ret = String
def extract(r: Record): Ret = r.brand
}
case object Product extends Dimension with DimExtractor[Record] {
type Ret = Int
def extract(r: Record): Ret = r.prodId
}

case class Record(custId: Long, prodId: Int, brand: String)

现在你可以把你的例子写成

val aRecord = Record(1, 1, "asd")
Seq[DimExtractor[Record]](Brand, Customer).foreach { d => println(d.extract(aRecord)) }

关于Scala Generics - ADT 中的通用提取器方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28542929/

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