1

在 scala 中指定以下概念的最简洁方法是什么?该概念表示通用提取器函数的接口,该函数指定了在编译时提取的类。

合同的定义

import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import scala.collection.JavaConversions._

trait ExtractorBase {
  type ExtractedType
  type RetType = Tuple2[Option[Seq[ExtractedType]],Option[Seq[String]]]
  type ExtractorFunction = (Document) => RetType
  def extractor : ExtractorFunction
}
class Extractor[T] (extractor_in: Any) extends ExtractorBase {
  type ExtractedType = T
  val extractor : ExtractorFunction = extractor_in
}

构造实例

//type TFunc = (Document) => Tuple2[Option[Seq[Int]],Option[Seq[String]]]
val ex = new Extractor[Int]( (x: Document)=> {
    (Some(Seq(1)),Some(Seq("hassan")))
})

目前提取器功能也没有正确混叠:

[error] /Users/hassan/code/scala/extractor/hon.scala:14: type mismatch;
[error]  found   : Any
[error]  required: org.jsoup.nodes.Document => (Option[Seq[Extractor.this.ExtractedType]], Option[Seq[String]])
[error]     (which expands to)  org.jsoup.nodes.Document => (Option[Seq[T]], Option[Seq[String]])
[error]   val extractor : ExtractorFunction = extractor_in
  • 如何在扩展特征的类的定义之外引用通用特征数据?在编译时和运行时。例如编译时间我宁愿有:

    特征 ExtractorBase[T] { type ExtractedType = T type RetType = Tuple2[Option[Seq[ExtractedType]],Option[Seq[String]]] type ExtractorFunction = (Document) => RetType def extractor : ExtractorFunction }

接着

class Extractor[T] (extractor_in: ExtractorBase[T].ExtractorFunction) extends ExtractorBase

有点类似于 C++ 特征。

  • 在运行时,我也不介意获取特征中的类型信息。

  • 可能有一种更惯用的方式来创建特征实例,我不想通过Extractor[T]课程。有没有办法用 trait 的伴生对象来做到这一点?

编辑

Ankur 的回答使我走上了正确的道路。我的曲目中缺少 # 运算符。时间来打扮这个。

trait ExtractorBase[T] {
  type ExtractedType = T
  type RetType = Tuple2[Option[Seq[ExtractedType]],Option[Seq[String]]]
  type ExtractorFunction = (Document) => RetType
  def extractor : ExtractorFunction
}
class Extractor[T] (extractor_in: ExtractorBase[T]#ExtractorFunction) extends ExtractorBase[T] {
  def extractor : ExtractorBase[T]#ExtractorFunction = extractor_in
}

导致 :

val ex = new Extractor[Int]( (x: Document)=> {
      (Some(Seq(1)),Some(Seq("hassan")))
})
4

1 回答 1

0

可以如下定义使用 jsoup 的提取函数的可能通用规范,该规范可以检索通用 url 和项目(或两者,或两者之一,或无)。它是功能性的,并且是惯用的 afaik。如果可以改进,请提供意见。

import org.jsoup.nodes.Document

object ExtractorTraits {
  case class UrlPair[T](data: String, payload: Option[T])
  case class ResultPair[T,U](items: Option[Seq[T]],urls:  Option[Seq[UrlPair[U]]] = None)

  trait ItemExtractorTrait[I,C] {
    type ExtractedType = I
    type RetType = Option[Seq[ExtractedType]]
    type ExtractorFunction = (Document,Option[C]) => RetType
    def apply : ExtractorFunction
  }
  class ItemExtractor[I,C](extract_item : ItemExtractorTrait[I,C]#ExtractorFunction = (doc : Document,c: Option[C]) => None)
    extends ItemExtractorTrait[I,C] { val apply = (doc: Document, ctxt: Option[C]) => extract_item(doc,ctxt) }

  trait UrlExtractorTrait[U,C] {
    type UrlPayload = U
    type RetType = Option[Seq[UrlPair[U]]]
    type ExtractorFunction = (Document,Option[C]) => RetType
    def apply : ExtractorFunction
  }
  class UrlExtractor[U,C](extract_url : UrlExtractor[U,C]#ExtractorFunction = (doc:Document,c : Option[C]) => None)
    extends UrlExtractorTrait[U,C] { val apply = (doc: Document, ctxt:  Option[C]) => extract_url(doc,ctxt)}

  trait ExtractorTrait[I,U,C] {
    type RetType = ResultPair[I,U]
    type ExtractorFunction = (Document, Option[C]) => RetType
    def apply : ExtractorFunction
  }
  class Extractor[I,U,C] (item_extractor: ItemExtractorTrait[I,C]#ExtractorFunction = new ItemExtractor[I,C]().apply,
                        url_extractor: UrlExtractorTrait[U,C]#ExtractorFunction = new UrlExtractor[U,C]().apply) extends ExtractorTrait[I,U,C] {
    val apply = (doc: Document, ctxt: Option[C]) => ResultPair[I,U](item_extractor(doc,ctxt),url_extractor(doc,ctxt))
  }
}

编辑

拆分功能特征,以便它们可以单独使用。

编辑2

提取器现在有上下文

于 2013-11-14T12:43:08.597 回答