Reputation: 934
I'm trying to do the following
type Foo{T}
x::changeType(T)
end
where the function changeType
changes the type parameter to some other type. It doesn't have to be a function, I'm happy using a dictionary or a macro or w/e, I just need a way to do this.
I tried it with both a function and a dictionary and both resulted in errors.
Upvotes: 3
Views: 228
Reputation: 15889
I believe this is not entirely possible. However, you can play with a couple of workarounds.
Do not constrain the type of x
and just instantiate x
with the proper type manualy:
type Foo{T}
x
y::T
end
>>> f = Foo{Int32}(5.0f0, 2)
Foo{Int32}(5.0f0,2)
>>> typeof(f.x), typeof(f.y)
(Float32, Int32)
You can wrap your object in a function:
const types = Dict(Int64 => Float32)
type Foo{T}
x::T
end
foo(k) = Foo{get(types, T, T)}
Then create an object of Foo
>>> foo(Int64)
Foo{Float32}
If you want to have mixed type fields in the same type
(e.g. fields of T
and map(T)
) you can modify a bit the constructor:
const types = Dict(Int64 => Float32)
type Foo{T}
x
y::T
Foo(x=0, y=0) = new(get(types, T, T)(x), y)
end
This will allow you to create Foo
as Foo{Int64}
while mapping x
to Float32
:
>>> Foo{Int64}(5, 2)
Foo{Int64}(5.0f0, 2) # x is Float32, y is Int64
And the last, and probably the most viable one: first define the dictionary and wrap your type
in both types
:
const types = Dict(Int64 => Float32)
type Foo{T, V}
x::V
y::T
end
Now wrap the construction of a Foo
object into a function:
foo(T) = Foo{T, get(types, T, T)}
foo(T, args...) = Foo{T, get(types, T, T)}(args...)
foo
function creates objects of type Foo
where the first parameter specifies the type T
of Foo
and the type V
is dynamically inferred from the types
dictionary.
>>> foo(Int64)
Foo{Int64,Float32}
>>> foo(Int64, 5, 2)
Foo{Int64,Float32}(5.0f0,2) # x is Float32, y is Int64
Note: in both the above methods, if T
is not defined in the types
dictionary, the get
function returns T
and thus x
is mapped to T
. Is a fall-back method for types that don't require mapping. E.g. for the third option:
>>> Foo{Int32}(5, 2)
Foo{Int32}(5,2)
both x
and y
are Int32
since Int32
is not in the mapping dict types
. And for the fourth option:
>>> foo(Int32)
Foo{Int32,Int32}
I think currently the type of x
cannot be specified at compile time as a function of T
, but the above workarounds should do the job.
I don't know neither how smart is the Julia compiler.. given that the types
dictionary is constant, it might do some smart things and infer the type of x
from there (maybe a dev could answer this or give further improvements).
Upvotes: 3