4

In few examples, I have seen that an object or a class extends Function1.

E.g. object Cash extends (CashProduct => String) in Hidden features of Scala

(I suppose A => B means Function1)

What it the benefit of extending a Function1?

Maroun
  • 94,125
  • 30
  • 188
  • 241
Manu Chadha
  • 15,555
  • 19
  • 91
  • 184

2 Answers2

2

The full example of what you provided:

object Cash extends (CashProduct => String) {
  def apply(p: CashProduct) = p.currency.name + "="

  def unapply(s: String)(implicit ps: ProductService): Option[CashProduct] = {
    if (s.endsWith("=") 
      Some(ps.findCash(s.substring(0,3))) 
    else None
  }
}

Shows that OP wanted to gain the syntactical benefit of the apply method, which allows your to create an instance calling Cash(...).

But why would you really want to extend a function? Lets look at a better case perhaps, List[T].

If we look up the long inheritance hierarchy, we'll see that:

trait Seq[+A] extends PartialFunction[Int, A]  

Hmm, why does Seq extend PartialFunction[Int, A] (which in turns inherits Function1[A, B]? Because if we think about it, if I pass a List[A] an Int, representing the index of the element I'm seeking, it will (not efficiently) return me the element at that given index (if present).

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • I understood the explanation for `Seq`. Am I correct that in OP's example, there is no need to extend `CashProduct => String` because the OP is using `apply` to avoid using `new` keyword when creating `Cash` (similar to `val l = List(1,2,3)`. OP is not using the `apply` and `isDefinedAt` of `PartialFunctions` to do something like `Cash(cp)` to get value (similar to `l(1)` which would return `2`) – Manu Chadha Nov 28 '17 at 18:05
  • @ManuChadha You're right. The same would work if OP would just supply `def apply` without extending function. – Yuval Itzchakov Nov 28 '17 at 18:07
1

The benefit of extending Function1 as compared to just defining apply is just that you can pass this object where a Function1 is expected. E.g.

val products: List[CashProduct] = ...
products.map(Cash)

Without the extends it would have to be written as

val products: List[CashProduct] = ...
products.map(Cash(_)) 
// or products.map(Cash.apply)
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487