R Scala中的管道算子

R Scala中的管道算子,r,scala,R,Scala,我想知道是否可以在R语言的magrittr包中定义管道操作符,如%%>%。我发现了几个类似的实现,如下所示: implicit class PipelineContainer[F](val value: F) { def |>[G] (f: F => G) = f(value) } 因此x |>f |>g的工作原理类似于g(f(x)) 现在,我希望这个操作符即使在函数接受超过1个参数时也能工作,在这种情况下,管道参数左侧的值成为右侧函数的第一个参数。例如,x |>f(2)|>g

我想知道是否可以在
R
语言的
magrittr
包中定义管道操作符,如
%%>%
。我发现了几个类似的实现,如下所示:

implicit class PipelineContainer[F](val value: F) {
  def |>[G] (f: F => G) = f(value)
}
因此
x |>f |>g
的工作原理类似于
g(f(x))


现在,我希望这个操作符即使在函数接受超过1个参数时也能工作,在这种情况下,管道参数左侧的值成为右侧函数的第一个参数。例如,
x |>f(2)|>g(3)
变成
g(f(x,2),3)
。如何在scala中实现这一点?它不必与我在这里展示的语法相同,但越简单越好。

有几个选项

一种是只创建内联函数。只是有点乱

x |> (z=>f(z,2)) |> (z=>g(z,3))
另一种方法是创建可以折叠现有函数的arity的快捷方式方法。一般来说,这是很多样板,但第一个很简单:

implicit class RichPipes[Y](y: Y) {
  def |>[Z](f: Y => Z) = f(y)
  def &>[X, Z](f: (X, Y) => Z): (X => Z) = (x: X) => f(x, y)
}
然后,您可以将其他参数插入到内联中(利用
&
的优先级高于
|
这一事实):

就我个人而言,我觉得这种风格令人困惑,但编译器可以使用它

另一个选项是将方法转换为要开始的函数(如果需要),然后对这些函数进行充实,使其具有部分应用程序助手方法:

implicit class RichFunction2[A,B,Z](f: (A,B) => Z) {
  def %(b: B): (A => Z) = (a: A) => f(a,b)
}
现在你可以

x |> f _ % 2 |> g _ % 3
最后,如果您碰巧能够以不同的方式编写函数,则可以在不使用任何额外机制的情况下使其正常工作,只需保留一个尾随的
\uuu
,以便让编译器知道您在做什么;不同之处在于,应用程序要经过多个参数块中的最后一个:

def h(y: Int)(x: Int) = x + y
def i(y: Int)(x: Int) = x * y

x |> h(2) _ |> i(3) _
不过,作为最后一个想法,对于新手来说,在中途注入参数可能不是最容易做到的事情。您可能会考虑它是好的编程实践,而不是采用不同的工作流。

def h(y: Int)(x: Int) = x + y
def i(y: Int)(x: Int) = x * y

x |> h(2) _ |> i(3) _