Reputation: 77
I am new to Scala and try to focus on more functional programming side of it.
I am trying to write a function filter.
Here is a definition and implementation:
def filter[A, B](f: A => Boolean, l: List[A]): List[B] = l match {
case Nil => List()
case x :: xs => if (f(x)) (x: B) :: filter(f, xs) else filter(f, xs)
}
Using this function, I get this error: :32: error: type mismatch;
found : x.type (with underlying type A)
required: B
case x :: xs => if (f(x)) (x: B) :: filter(f, xs) else filter(f, xs)
Now, before that I wrote a function map:
def map[A, B](f: A => B, l: List[A]): List[B] = l match {
case Nil => List()
case x :: xs => f(x) :: map(f, xs)
}
that actually applies function f to convert each list element from type A to type B.
My error for filter seems to be caused by the fact that function taken by filter does nothing to list element x of type A, so type checker thinks that I am still building a list of type A when B is required. You can see I tried to specify x as type B but it was in vain. Can anyone confirm that I understood problem correctly and how can I make x as type B? I could just return list of type A but this is a function definition that is given as an exercise and I cannot change it.
Upvotes: 2
Views: 1715
Reputation: 8462
Your filter method seems to try converting A
to B
which is not what filter methods usually do. A
and B
are two unrelated types, so you cannot cast between them
You would want something like that:
def filter[A](l: List[A])(f: A => Boolean): List[A] = l match {
case Nil => List()
case x :: xs => if (f(x)) x :: filter(xs)(f) else filter(xs)(f)
}
But you also can write this one a bit simpler:
def filter[A](l: List[A])(f: A => Boolean): List[A] =
for (x <- l if f(x)) yield x
Please also notice that I have swapped the arguments and divided them. This is done in order for scala's type inference to infer A
automatically. Now you can do this:
filter(List(1, 3, 5, 7))(_ > 4)
where Int
type is infered implicitly
Upvotes: 2