2013-11-14 70 views
0

在scala中指定以下概念的最新方法是什麼?該概念表示一個通用提取函數的接口,該接口指定了在編譯時正在提取的類。 ContructScalla中的基本元編程技巧

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

的Contruct

定義

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 
} 

實例在瞬間提取函數沒有被正確走樣之一:

[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] { 類型ExtractedType = T 型RetType = Tuple2 [選項[序號[ExtractedType],選項[SEQ [字符串]]] 類型ExtractorFunction =(文件)=> RetType DEF提取:ExtractorFunction }

然後

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

類似於C++特徵的類型。

  • 在運行時,我不介意在特徵中獲取類型信息。

  • 有可能是一個更習慣的方式來創建特質的實例,我不想去通過Extractor[T]類。有沒有辦法與特質的伴侶對象做到這一點?

編輯

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"))) 
}) 

回答

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)) 
    } 
} 

編輯

拆分功能性狀起來,以便他們能夠另行制定。

EDIT2

提取現在有背景