【问题标题】:scala, general purpose transform function for all objectsscala,所有对象的通用变换函数
【发布时间】:2013-07-03 13:07:13
【问题描述】:

我想要的东西如下:

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

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

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 库中的某个地方实现了?

【问题讨论】:

    标签: scala


    【解决方案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)
    

    【讨论】:

    • 示例无法编译(错误“未找到:值 |>”)。我将依赖项添加到 scalaz-core_2.10 7.0.0,并导入 scalaz._ 我需要其他东西来编译它吗?并且,是否有 API 文档?我只在github.com/scalaz/scalaz 找到了通用文档页面
    • 您需要从scalaz.syntax.id._ 导入隐式。我已将此添加到我的答案中。
    • 太好了,谢谢!某处有api文档吗?我应该如何找到有关 syntax.id 的信息?
    • 对于 API 文档,请尝试 bit.ly/scalaz-7-docseed3si9n.com/learning-scalaz-day13 对语法隐含有很好的解释
    猜你喜欢
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    相关资源
    最近更新 更多