(This is more of a conceptual question, so I am posting in this category, please reassign if inappropriate. Also, I don’t have a formal CS background, so this may have an obvious answer I missed. Thanks for your understanding.)
Ever since learning about Nullables and reading Joe Duffy’s blog post about the Midori Error Model which was mentioned in #7026, I have been trying to structure my code to handle missing values using these concepts.
Frequently I encounter the following situation: I would like to have some operation which is well-defined on actual values, and I would like to lift it to work on Nullables. To make things concrete, suppose the operation maps a single argument to a single result. There seems to be a standard way of doing this with a combinator, which is called and_then in Rust. My problem with implementing this in Julia is that if the value is null, then I cannot call f
, so I don’t have a type to use in the Nullable. For example, if I wanted to implement it like
function and_then{T}(f, x::Nullable{T})
if isnull(x)
Nullable{return_type(f, Tuple{T})}() # hypothetical
else
Nullable(f(get(x)))
end
end
then I would need to define return_type
. The following works, most of the time, but it seems like a hack:
function return_type(f, types)
rt = Base.return_types(f, types)
@assert length(rt) == 1 "Could not infer a single return type."
rt[1]
end
Examples:
julia> f(x) = x+1
f (generic function with 1 method)
julia> and_then(f, Nullable(1))
Nullable{Int64}(2)
julia> and_then(f, Nullable{Int64}())
Nullable{Int64}()
julia> and_then(f, Nullable{String}()) # but f does not work on strings
Nullable{Any}()
I could of course provide the return type manually. But this becomes unwieldy when it is rather complex.
Is there a way to implement and_then
in Julia in some more natural way? Or if not, is this something I should forget about because this is not a good match for the concepts of the language, or are there plans to make it work better?