2017-01-23 65 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

是啊。我的错误 - 谢谢。 –