有状态功能管道

Wei*_*Lin 4 closures functional-programming pipeline scala purely-functional

代码解释了自己.

val s = Seq(1,1,1)
val res: Seq[Int] = s.map(...)
                     .check(count how many 1s, if > 2 throw Exception)
                     .map(...)
Run Code Online (Sandbox Code Playgroud)

我正在寻找这个check功能的简单解决方案.

  • 我可以使用mapclosure计数和投掷,但我想要纯粹的功能.
  • 我可以使用filtersizereduce,但它返回一个值,不能用以下地图恢复.

如何做一个纯粹的有状态的检查,管管道?

Rex*_*err 5

抛出异常可以说是不纯粹的.如果您使用的是monadic形式的错误处理,那么您可以执行以下操作:

Option(s.map(foo)).
  filter(m => m.count(_ == 1) < 2).
  map{ s =>
    s.map(bar)
     .filter(baz)
     ...
  }
Run Code Online (Sandbox Code Playgroud)

实际上,如果您想在管道中组合它,并且您不希望根据需要添加额外的括号,则match可以使用常用的tap方法:

implicit class TapAnything[A](private val a: A) extends AnyVal {
  def tap[U](f: A => U): A = { f(a); a }
}
Run Code Online (Sandbox Code Playgroud)

现在你可以

s.map(...)
 .tap(self => if (self.count(_ == 1) > 1) throw new Exception)
 .map(...)
 ...
Run Code Online (Sandbox Code Playgroud)

(注意:private val+ extends AnyValstuff只是为了向编译器表明它应该试图避免创建一个额外的对象来进行调用).