Defunctionalization

Functionalized

def filter[A](k: A => Boolean)(xs: List[A]): List[A] =
  xs match {
    case Nil => Nil
    case h::t => if (k(h)) h :: filter(k)(t) else filter(k)(t)
  }
val isEven: Int => Boolean =
  x => x % 2 == 0

println(filter(isEven)((1 to 10).toList)) // List(2, 4, 6, 8, 10)

Defunctionalized

trait Filter[A] {
  def apply(x: A): Boolean
}
case object IsEven extends Filter[Int] {
  def apply(x: Int): Boolean = isEven(x)
}

def filterD[A](f: Filter[A])(xs: List[A]): List[A] =
  xs match {
    case Nil => Nil
    case h::t => if (f(h)) h :: filterD(f)(t) else filterD(f)(t)
  }
println(filterD(IsEven)((1 to 10).toList)) // List(2, 4, 6, 8, 10)

References