If I understand your problem correctly I would say that you do not have to think about it, because the compiler will know the required types. For example in your code above when you would call first(c)
(this would be an equivalent of c.first()
) the type of this variable will be known at compile time (you can confirm this by running @code_warntype
on your function).
If you would provide a complete small working example I could give you a working code for this.
A more advanced topic is attaching some metadata to your types. There are several ways you could do it. Let me show you one of them - via a parametric abstract type.
abstract type AbstractCollection{T} end
struct PersonalDetail end
struct AddressBook <: AbstractCollection{PersonalDetail} end
struct Photo end
struct PhotoAlbum <: AbstractCollection{Photo} end
getcollectiontype(::AbstractCollection{T}) where T = T
and now you can write something like this to extract the metadata
julia> ab = AddressBook()
AddressBook()
julia> pa = PhotoAlbum()
PhotoAlbum()
julia> getcollectiontype(ab)
PersonalDetail
julia> getcollectiontype(pa)
Photo
Of course it is a MWE, and I am not sure if you need it in your code (if you show a small full working code we can discuss the best implementation strategy).
Also something like this might be not needed at all. For example you have a standard function eltype
that is expected to return a type of element in a collection. For this function you could add methods for your specific types to get the information about element type they hold. Then you can simply run eltype(collection)
in your code and again - at compile time - you will have the information about element type of the collection.
Also note that types in Julia as also values so for example the following code just works and compiler knows all types as need (the function f
tries to convert its second argument y
to the type of its first argument x
using the type constructor):
julia> f(x,y) = typeof(x)(y)
f (generic function with 1 method)
julia> f(10, 2.0)
2
julia> f(10.0, 2)
2.0
julia> @code_warntype f(10.0, 2)
Body::Float64
1 ─ %1 = (Base.sitofp)(Float64, y)::Float64
└── return %1
The definition above is equivalent to the following one f(x::T,y) = T(y)
.