scala,所有对象的通用转换函数

时间:2013-07-03 13:07:14

标签: scala

我想要有如下内容:

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));

也就是说,我只想在isNice时应用onlyNice==true过滤器。 我可以这样做:

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

但这会降低性能,因为即使onlyNice为false,我们也会遍历所有列表。

我们可以这样做:

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

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

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

但这更难以阅读。

这对我来说似乎是一个很好的通用解决方案:

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));
你觉得怎么样?

这个transform函数已经在某个标准的scala库中实现了吗?

1 个答案:

答案 0 :(得分:1)

您的transform实际上是功能应用程序的翻转形式。

我不知道标准库中的实现,但它在Scalaz库中实现为|>运算符,例如。

import scalaz.syntax.id._

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

请注意,因为在这种情况下,函数的类型为A => A而不是A => B(即它是List[String] => List[String]),您可以等效地使用identity函数,例如

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