Scala's equivalence to |> in F# or ->> in Clojure

那年仲夏 提交于 2019-12-12 13:17:45

问题


In Scala, when I have this expression

f1 ( f2 ( f3 (p))) 

Is there a way that I can use something like in

F#

p |> f3 |> f2 |> f1 

or Clojure?

(->> p f3 f2 f1)

回答1:


If you want to write it yourself without using external libraries,

implicit class Pipe[T](x: T) {
  def |> [U](f: T=>U): U = f(x)
}

So, this implicit class pattern is used for extension methods. It's shorthand for the "pimp my library" pattern:

class Pipe[T](x: T) { /*extension methods here*/ }
implicit def anyToPipe[T](x: T) = new Pipe(x)

As with any implicit conversion, if the method name is not valid for T, but there is a function T => Pipe in implicit scope, and the method is valid on Pipe, the function (or method here - effectively the same thing) is inserted by the compiler so you get a Pipe instance.

def |> [U](f: T=>U): U = f(x)

This is just a method called |> that has a parameter f of type T=>U, i.e. a Function1[T,U], where T is the input type and U is the result type. Because we want this to work for any type, we need to make the method type-parameterized on U by adding [U]. (If we used T=>Any instead, our return would be of type Any, which wouldn't be much use.) The return value is just the application of the function to the original value, as required.




回答2:


There is no equivalent to F#'s pipe operator in Scala...

... but there is one in the scalaz library. And it's also named |>. They nicknamed it the "thrush operator".

import scalaz._
import Scalaz._

def f(s: String) = s.length

"hi" |> f

Here's the scaladoc.



来源:https://stackoverflow.com/questions/32506410/scalas-equivalence-to-in-f-or-in-clojure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!