如何将转换链的结果传递给函数?

est*_*lua 8 scala higher-order-functions

我想写一个转换链,最后有一个块,我在那里用生成的集合做一些事情,而不使用变量.在集合上是否有一个更高阶的函数,它只提供它被调用到所提供函数的集合?

Query( ... )
  .map { ... }
  .filter { ... }
  .combinations(2)
  .pipeTo { col =>
     ...
     consolidate(col)
  }
Run Code Online (Sandbox Code Playgroud)

当然对于单个函数调用,可以这样做:

consolidate(
  Query()
    .map { ... }
    .filter { ... }
    .combinations(2)
)
Run Code Online (Sandbox Code Playgroud)

但是前者对我来说更自然,并允许例如容易注入一些条件.

我一直在使用的解决方法是在最后放置一个匹配子句:

Query()
  .map { ... }
  .filter { ... }
  .combinations(2)
  match { case lst =>
    ...
    consolidate(lst)
  }
Run Code Online (Sandbox Code Playgroud)

但由于这种模式经常发生,我想知道写这个的惯用方法是什么.

kon*_*ong 7

也许最习惯的方式是使用所谓的Pimp My Library Pattern,它允许通过隐式类转换向任何类添加扩展方法.

例如,要向s 添加consolidate方法List,您可以编写:

object ListExtensions {
  implicit class ConsolidatableList[T](val lst: List[T]) extends AnyVal {
    def consolidate = ??? // Do whatever you want with the List lst
  }
}

import ListExtensions._

List(1,2,3)
  .map(x => x * x)
  .consolidate
Run Code Online (Sandbox Code Playgroud)

如果你真的希望能够在链中的任意对象上调用任意函数,你甚至可以在F#中定义一个"管道"运算符:

object Extensions {
  implicit class PipelineExtension[T](val obj: T) extends AnyVal {
    def |>[S](f: T => S): S = f(obj)
  }
}

import Extensions._

List(1,2,3)
  .map(x => x * x) 
  .|> (consolidate)

Query( ... )
  .map { ... }
  .filter { ... }
  .combinations(2)
  .|> { col =>
     ...
     consolidate(col)
  }
Run Code Online (Sandbox Code Playgroud)

|>运营商的行为,如pipeTo你已经定义的方法.

基本上,这可以通过使用您定义的各种扩展方法创建从类型到类型的隐式转换.将AnyVal使得扩展类的值类,所以它的使用将有很少或几乎没有运行成本.