Reputation: 41939
Given the following, I believe, type class:
trait Element[A, B] {
val input: A
val filteredValue: Option[B]
}
I then defined filterFn
to filter on input queryFilterValues
, and then filter the curried List[A]
, returning a List[A]
, i.e. what's been filtered:
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)
}
}
Then, I created a Person
, along with an Person => Element[Person, String]
instance:
case class Person(name: Option[String])
object Person {
implicit def personToElement(p: Person) = new Element[Person, String] {
val input = p
val filteredValue = p.name
}
}
Finally, I tried to use it:
// 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) )
But I get the following compile-time error:
<console>:20: error: type mismatch;
found : List[Person]
required: ? => Element[?,String]
filterFn( nameFilters )( List[Person](joe) )
Upvotes: 1
Views: 76
Reputation: 2128
The signature of filterFn is
def filterFn[A, B](queryFilterValues: List[B])
(implicit ev: A => Element[A, B])
When you call it with
filterFn( nameFilters )( List[Person](joe) )
You're passing in List[Person](joe)
as the 2nd argument. But the signature you have defined expects a function from A
to Element[A, B]
This is why you see
found : List[Person]
required: ? => Element[?,String]
Upvotes: 3