So, I got some code which compiles, but it seems it can’t be instantiated. I think this is something about a quirk with union types that I remember reading about, but I’m not sure what to do about it.
module FakeLists
export cons, list
const Opt = Union{Nothing,T} where T
abstract type AbstractFakeList{T} end
struct InnerVector{L<:Opt{<:AbstractFakeList},T}
_tail::L
_v::Vector{T}
end
struct FakeList{T} <: AbstractFakeList{T}
_idx::UInt
_iv::InnerVector{Opt{FakeList{T}},T}
end
FakeList(i, v, tail) = FakeList(UInt(i), InnerVector(tail, v))
# ...
end # module
So that all compiles fine, but:
julia> FakeLists.FakeList(0, FakeLists.InnerVector(nothing, Char[]))
ERROR: MethodError: no method matching FakeLists.FakeList(::Int64, ::FakeLists.InnerVector{Nothing,Char})
Closest candidates are:
FakeLists.FakeList(::Any, ::Any, ::Any) at /home/ninjaaron/src/julia/FakeLists/src/FakeLists.jl:19
Stacktrace:
[1] top-level scope at none:0
julia> FakeLists.FakeList(0, [], nothing)
ERROR: MethodError: no method matching FakeLists.FakeList(::UInt64, ::FakeLists.InnerVector{Nothing,Any})
Closest candidates are:
FakeLists.FakeList(::Any, ::Any, ::Any) at /home/ninjaaron/src/julia/FakeLists/src/FakeLists.jl:19
FakeLists.FakeList(::UInt64, ::FakeLists.InnerVector{Union{Nothing, FakeList{T}},T}) where T at /home/ninjaaron/src/julia/FakeLists/src/FakeLists.jl:15
Stacktrace:
[1] FakeLists.FakeList(::Int64, ::Array{Any,1}, ::Nothing) at /home/ninjaaron/src/julia/FakeLists/src/FakeLists.jl:19
[2] top-level scope at none:0
I don’t get it. I would have thought InnerVector{Union{Nothing, FakeList{T}},T}) where T
would include InnerVector{Nothing,Any}
, but it appears I am mistaken. Any suggestions?