为什么在 lambda 工作时重写为 Julia do 块中断?

Why does this rewrite to a Julia do block break when the lambda works?

我有这个 lambda 风格的函数调用

foldr((l,r) -> r+1, "12345"; init=0)

Julia 很乐意将其计算为 5。将其重写为 do 样式看起来像

foldr("12345"; init=0) do (l,r)   # I also tried ((l,r),) and just tup
    # l,r = tup   # and then destructure here
    r+1
end

据我了解,这两个应该是等价的。不幸的是,Julia 1.7.0-rc3 不同意我的观点:

ERROR: MethodError: no method matching (::var"#36#37")(::Char, ::Int64)
Closest candidates are:
(::var"#36#37")(::Any) at REPL[25]:2
Stacktrace:
[1] FlipArgs
@ ./reduce.jl:196 [inlined]
[2] BottomRF
@ ./reduce.jl:81 [inlined]
[3] _foldl_impl(op::Base.BottomRF{Base.FlipArgs{var"#36#37"}}, init::Int64, itr::Base.Iterators.Reverse{String})
@ Base ./reduce.jl:58
[4] foldl_impl(op::Base.BottomRF{Base.FlipArgs{var"#36#37"}}, nt::Int64, itr::Base.Iterators.Reverse{String})
@ Base ./reduce.jl:48
[5] mapfoldr_impl(f::Function, op::Function, nt::Int64, itr::String)
@ Base ./reduce.jl:186
[6] #mapfoldr#246
@ ./reduce.jl:205 [inlined]
[7] #foldr#247
@ ./reduce.jl:224 [inlined]
[8] top-level scope
@ REPL[25]:1

为什么第一种形式有效而第二种形式无效?它可以工作吗?

此处不需要括号:

julia> foldr("12345"; init=0) do l, r
           r+1
       end
5

如果你在 do 之后写 (l, r) 这意味着你正在传递一个参数,该参数有两个元素应该分别分配给 lr,例如:

julia> foreach([1:2, 3:4, 5:6]) do (x,y)
       @show x
       @show y
       end
x = 1
y = 2
x = 3
y = 4
x = 5
y = 6

有关此规则的其他说明,请参阅 Julia Manual