【问题标题】:Scala Generics - generic extractor method in an ADTScala Generics - ADT 中的通用提取器方法
【发布时间】:2015-02-16 23:14:05
【问题描述】:

我有一个类似的 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]...但这似乎也不对。

有什么更好的方法来做到这一点?

【问题讨论】:

    标签: scala generics


    【解决方案1】:

    您有 Dimension 特征的 3 个子类(对象),提取器的返回值取决于参数类型(将 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)) }
    

    【讨论】:

      猜你喜欢
      • 2017-08-19
      • 1970-01-01
      • 2018-10-22
      • 1970-01-01
      • 1970-01-01
      • 2019-06-26
      • 1970-01-01
      • 2019-02-06
      • 1970-01-01
      相关资源
      最近更新 更多