This code does not work, but I want to do something like the following (the general idea should be clear):
map_type(::Type{String}) = Int64
map_type(::Type{Int64}) = String
struct Foo{T}
a::map_type(T)
end
Basically the function map_type can be fully resolved at compile time so one could imagine a world where this works. But if you enter this in to the REPL you will see
ERROR: MethodError: no method matching map_type(::TypeVar)
Closest candidates are:
map_type(::Type{String})
map_type(::Type{Int64})
Is there a way to achieve such a thing? Presumably in a real world use case the map_type
function would be a little more complicated. A motivating example may be to do the following transformation:
map_type(::Val{N}, ::Type{T}) where T <: NTuple{N, Real} where N = begin
[Foo{fieldtype(T, i)} for i in 1:N]
end
struct Foo{T <: Real}
a :: T
end
struct Bar{N, T <: NTuple{N, Real}}
foos::Tuple{map_type(Val(N), T)...}
end
This doesn’t work, but the idea is to allow Bar
to contain a variable number of differently parameterized Foo
s in a type-stable way.
I understand this is bordering abuse of the type system, but I have a use case in mind for creating a time series iterator that merges a variable number of other time series iterators (output in chronological order from multiple iterators). Obviously the output of such an iterator would not be type-stable (unless all underlying iterators output the same type), but it could be restricted to a small Union
type so that the compiler could still use a union splitting optimization for performance. (Or at least that is my theory)