2017-01-23 49 views
1

給出下面,我相信,類型類:撰寫一般過濾器類型類?

trait Element[A, B] { 
    val input: A 
    val filteredValue: Option[B] 
    } 

我再定義filterFn過濾輸入queryFilterValues,然後篩選咖喱List[A],返回List[A],即什麼是被過濾:

def filterFn[A, B](queryFilterValues: List[B]) 
        (implicit ev: A => Element[A, B]): List[A] => List[A] = 
    elements => { 
    queryFilterValues match { 
     case _ :: _ => elements.flatMap { e => 
      ev(e).filteredValue match { 
      case Some(v) => if(queryFilterValues.contains(v)) List(e.input) else Nil 
      case None => List.empty 
      } 
     } 
     case Nil => elements.map(_.input) 
     } 
    } 

然後,我創建了一個Person,以及一個Person => Element[Person, String]實例:

case class Person(name: Option[String]) 
object Person { 
    implicit def personToElement(p: Person) = new Element[Person, String] { 
    val input   = p 
    val filteredValue = p.name 
    } 
} 

最後,我想用它:

// Filter on these names 
val nameFilters = List("jane", "joe", "will") 

val joe = Person(Some("joe")) 

// Expect to get a `List(joe)` back since `joe#name` exists in the list. 
scala> filterFn(nameFilters)(List[Person](joe)) 

,但我得到了下面的編譯時錯誤:

<console>:20: error: type mismatch; 
found : List[Person] 
required: ? => Element[?,String] 
     filterFn(nameFilters)(List[Person](joe)) 

回答

3

filterFn的簽名是

def filterFn[A, B](queryFilterValues: List[B]) 
       (implicit ev: A => Element[A, B]) 

當您打電話它與

filterFn(nameFilters)(List[Person](joe)) 

您作爲第二個參數傳入List[Person](joe)。但是,您所定義的簽名預計從AElement[A, B]

功能這就是爲什麼你看到

found : List[Person] 
required: ? => Element[?,String] 
+0

是啊。我的錯誤 - 謝謝。 –