julia - 没有更好的方法来组合多个 `Union{T, Nothing}`

标签 julia optional lazy-evaluation nothing

我对 Julia 很陌生,但我对 Scheme/Rust/F# 有一定的了解。
今天我想做yesterday's AoC没有明确数量的嵌套循环更好。
我找到了这个可行的解决方案,但我不喜欢最后一个 if .在上面提到的语言中,我会调用一个函数(或使用计算表达式),它给我的第一个结果不是 None .对于 Julia,我预计 something要做到这一点。它确实如此,但出乎意料地以一种热切的方式。
所以当我尝试 return something(find(r, n, start + 1, which), find(r, n - 1, start + 1, extended)) ,当第一个参数已经有结果时,它也会评估第二个参数 - 因此崩溃。
是否有宏/懒版本或 something我没找到?遇到这样的案子该怎么办?
我也想过(短路)或将它们放在一起,但我猜 Julia 在这件事上的严格破坏了这一点。

using DataStructures

function find(r::Array{Int}, n, start = 1, which = nil())::Union{Int,Nothing}
    if start <= length(r)
        extended = cons(start, which)
        with_current = sum(i -> r[i], extended)
        if with_current == 2020 && n == 1
            return prod(i -> r[i], extended)
        else
            # Unfortunately no :(
            #return something(find(r, n, start + 1, which), find(r, n - 1, start + 1, extended))
            re = find(r, n, start + 1, which)
            if isnothing(re)
                return find(r, n - 1, start + 1, extended)
            else
                re
            end
        end
    end
end

最佳答案

鉴于评论中的讨论,让我对为什么不可能进行更多评论。
在 Julia 函数参数中急切地求值,因此 Julia 对 find(r, n, start + 1, which) 都求值。和 find(r, n - 1, start + 1, extended)在将它们传递给 something 之前功能。
现在,有了你的宏(为了简单起见,我不是在一个完全通用的情况下写的,我希望我的卫生是正确的:)):

julia> macro something(x, y)
           quote
               local vx = $(esc(x))
               isnothing(vx) ? $(esc(y)) : vx
           end
       end
@something (macro with 1 method)

julia> @something 1 2
1

julia> @something nothing 2
2

julia> @something 1 sqrt(-1)
1

julia> @something nothing sqrt(-1)
ERROR: DomainError with -1.0:
sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
(在宏可变参数的完整版本中,应该处理 Some 以精确复制 something)

关于julia - 没有更好的方法来组合多个 `Union{T, Nothing}`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65110298/

相关文章:

Scala:访问 optional 对象中的 optional 值

loops - 为什么 Haskell 序列函数不能惰性或递归单子(monad)函数不能惰性

haskell - C++ 和 Haskell 中的树遍历

julia - 就地更新函数参数

julia - 使用 Plots.jl 显示多个图

julia - 如何使用列表理解创建二维数组?

scala - 覆盖值的行为的原理

csv - 有没有办法在 writetable() 中使用字符串作为分隔符 - Julia

scala - 简化 Scala 中的 Option[Boolean] 表达式

java - 里面的类型转换类型 Optional