Kevin Meredith
Kevin Meredith

Reputation: 41939

Write a General Filter Type Class?

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

Answers (1)

Metropolis
Metropolis

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

Related Questions