为什么 Julia 在组合匿名函数时不考虑链式函数中的最大函数?

Sha*_*yan 6 julia

我几天前才了解Julia 中的链接函数(如管道) 。今天我尝试了一些事情并得到了意想不到的结果。因此,我决定更好地询问问题的根源,以更好地理解 Julia 在链接函数中的行为。考虑这个例子:

\n
julia> a = [1 2 3]\n1\xc3\x973 Matrix{Int64}:\n 1  2  3\n
Run Code Online (Sandbox Code Playgroud)\n

然后我想链接一些像下面这样的函数,毕竟我想要整个矩阵的最大值:

\n
julia> a .|> x->x^2 .|> sqrt .|> Int64 |> maximum\n1\xc3\x973 Matrix{Int64}:\n 1  2  3\n
Run Code Online (Sandbox Code Playgroud)\n

但我期望只有一个3!为什么 Julia 不考虑链的最后一个函数,即函数maximum

\n

PS:另外,我也尝试过这样的方法:

\n
julia> a .|> x->x^2 .|> sqrt .|> Int64 |> x->maximum(x)\n1\xc3\x973 Matrix{Int64}:\n 1  2  3\n
Run Code Online (Sandbox Code Playgroud)\n

仍然不是我所期望的那样。

\n

kab*_*nus 4

问题实际上是箭头运算符而不是管道!管道很好。

请记住,如果您想检查解析顺序,则始终可以使用冒号运算符:

julia> :(a .|> x->x^2 .|> sqrt .|> Int64 |> maximum)
:(a .|> (x->begin
              #= REPL[84]:1 =#
              ((x ^ 2 .|> sqrt) .|> Int64) |> maximum
          end))
Run Code Online (Sandbox Code Playgroud)

箭头首先评估右侧的所有内容,然后通过管道传输左侧的结果(右关联),因此您所拥有的内容与以下内容相同:

a .|> x->(x^2 .|> sqrt .|> Int64 |> maximum)
Run Code Online (Sandbox Code Playgroud)

在右侧,您只需创建一个函数,将参数(在我们的示例中为单个数字)一直传输到最大值,映射只需执行 3 次即可给出结果。

你想要的是:

a .|> (x->x^2) .|> sqrt .|> Int64 |> maximum
Run Code Online (Sandbox Code Playgroud)

我通常会确保无论何时将箭头与管道一起使用,箭头都用括号括起来 - 否则这是非常违反直觉的!

如果你刚刚做了类似的事情

a .|> sqrt |> maximum
Run Code Online (Sandbox Code Playgroud)

你不会注意到这一点。请注意管道的关联性非常有意义 - 上面是

maximum(sqrt.(a))
Run Code Online (Sandbox Code Playgroud)

正如你所期望的那样。关于右箭头函数的问题是,它无法真正“知道”右侧的函数是什么,因此它只是解析所有内容。

  • 我建议将 `:(a .|> x->x^2 .|> sqrt .|> Int64 |> Maximum)` 的输出添加到答案中,这样可以清楚地表明 Julia 如何解析该表达式。谢谢你! (2认同)