score:8

Scala extractor companion objects should extend Function

For case classes, the compiler generates a companion object under the hood. This holds relevant static methods for the Wrapper case class, including apply. Peering at the bytecode, we discover that Wrapper's companion object extends Function1. (Actually it extends AbstractFunction1, which uses @specialized to obviate autoboxing.)

This is also noted here. Why do case class companion objects extend FunctionN?

When replacing our Wrapper case class with an extractor, we should take care to extend our home grown companion object with AbstractFunction1 to preserve backwards compatibility for our clients.

This amounts to a small tweak in the source code. The apply method doesn't change at all.

object Wrapper extends scala.runtime.AbstractFunction1[Int, Wrapper] {

score:12

Simply put, Wrapper (the object) isn't a Function, it's just an object with an apply method. This has absolutely nothing to do with the object also being an extractor.

Try this:

class Wrapper(val x: Int) {
  override def toString = "Wrapper(" + x + ")"
  // other methods elided
}

object Wrapper extends (Int => Wrapper) {
  def apply(x: Int) = new Wrapper(x)
  def unapply(w: Wrapper): Option[Int] = Some(w.x)
}

def higherOrder(f: Int => Wrapper) = println( f(42) )

I also made the parameter to Wrapper a val and swapped around the parameter and return value in your definition of unapply so that it would match case-class behaviour.


Related Query

More Query from same tag