scala, general purpose transform function for all

2019-08-07 13:42发布

问题:

I'd like to have something as follows:

val onlyNice = true;

val users: List[String] = getNames()
val result = users
  .filter(_.contains("john")
  .map(._toUpperCase)
  .filter(p => isNice)   // here i would need to apply this filter only if `onlyNice` is true
  .map(p => countryOf(p));

that is, I want to apply the isNice filter only if onlyNice==true. I could do it as follow:

val result = users
  .filter(_.contains("john")
  .map(._toUpperCase)
  .filter(p => !onlyNice || isNice)
  .map(p => countryOf(p));

but this would slow down performance, because we are traversing all the list even if onlyNice is false.

we could do as follows:

val tmp = users
  .filter(_.contains("john")
  .map(._toUpperCase)

val tmp2 = if (onlyNice) tmp.filter(isNice) else tmp

val result = tmp2.
  .map(p => countryOf(p));

but this is more difficult to read.

This seems a good generalized solution to me:

implicit class ObjectHelper[A](o: A) {
  def transform[B](f: A => B): B = f(o)
}

val result = users
  .filter(_.contains("john")
  .map(._toUpperCase)
  .transform(list => if (onlyNice) list.filter(isNice) else list)
  .map(p => countryOf(p));

what do you think?

is this transform function already implemented in the standard scala library somewhere?

回答1:

Your transform is essentially a flipped form of function application.

I don't know of an implementation in the standard library, but it is implemented in the Scalaz library as the |> operator, e.g.

import scalaz.syntax.id._

users |> (list => if (onlyNice) list.filter(isNice) else list)

Note that because in this case, the function is of type A => A rather than A => B (i.e. it is List[String] => List[String]), you can equivalently use the identity function, e.g.

users |> (if (onlyNice) (_.filter(isNice)) else identity)


标签: scala