2

我在几个地方读到 Julia 中的管道仅适用于只接受一个参数的函数。这不是真的,因为我可以执行以下操作:

function power(a, b = 2) a^b end
3 |> power
> 9

它工作正常。

但是,我无法完全理解管道。例如,为什么这不起作用?:

3 |> power()
> MethodError: no method matching power()

我实际上想做的是使用管道并定义其他参数,例如关键字参数,以便在管道时实际上清楚传递哪个参数(即唯一的位置参数):

function power(a; b = 2) a^b end
3 |> power(b = 3)

有没有办法做这样的事情?


我知道我可以解决这个包,但老实说,在一半行的开头Pipe写起来感觉有点笨拙。@pipe

在包中具有令人信服Rmagritrr逻辑(在我看来):它默认将管道左侧的内容作为右侧函数的第一个参数传递 - 我正在寻找类似的东西。

4

1 回答 1

4

power第一个片段中定义的有两种方法。一辩一辩,一辩二。因此,|>仅使用单参数方法的观点仍然成立。

您想要做的事情称为“部分应用程序”,在函数式语言中很常见。你总是可以写

3 |> (a -> power(a, 3))

但这很快就会变得笨拙。其他语言有类似power(%1, 3)表示 lambda 的语法。有讨论添加类似于 Julia 的内容,但很难做到正确。 Pipe正是针对它的基于宏的修复。

如果您可以控制已定义的方法,您还可以使用返回部分应用版本的接口实现方法 - Base 中的许多谓词已经这样做了,例如==(1). 也可以选择Base.Fix2(power, 3),但这并不是真正的改进,如果你问我(除了可能对编译器更好)。

请注意,magrittrs 管道也是基于“宏”的。不同之处在于,在 R 中传递的参数要复杂得多,并且您无法从外部看到参数是用作值还是用作表达式(本质上,R 传递了一个包含表达式和指向父环境的指针的 thunk , 如果您将其用作值,则会自动评估和缓存它;请参阅substitute)

于 2020-05-02T08:33:54.377 回答