Specify type when calling parametric function

Say I have a parametric function:

foo(a::Union{T, Vector{T}}) where {T} = T

Calling foo(ones(1)) returns Float64, implying that Julia has decided that a was of type Vector{T}. Is it possible to call this function explicitly specifying T as Vector{Float64}?

Calling foo(ones(1)) returns Float64 , implying that Julia has decided that a was of type Vector{T} .

Well, it is, so that’s not too surprising :wink:

But I’m not really sure what you want to know?

bar(a::T) where {T} = T

returns Array{Float64,1} (== Vector{Float64}) for bar(ones(1)), are you looking for that?

Not sure what you are asking about here, but

julia> foo([[1.0]])
Array{Float64,1}

which is a Vector{Float64}.

I’m trying to make this code more generic to allow for multidimensional individuals, with the function signature

function ga(objfun::Function, dims::Tuple;
            initPopulation::Union{T, Vector{T}, Function} = trues(dims),
            lowerBounds::Union{Nothing, Vector{T}} = nothing,
            upperBounds::Union{Nothing, Vector{T}} = nothing,
            populationSize::Int = 50,
            crossoverRate::Float64 = 0.8,
            mutationRate::Float64 = 0.1,
            ɛ::Real = 0,
            selection::Function = ((x,n)->1:n),
            crossover::Function = ((x,y)->(y,x)),
            mutation::Function = (x->x),
            iterations::Integer = 100*prod(dims),
            tol = 0.0,
            tolIter = 10,
            verbose = false,
            debug = false,
            interim = false) where {T}

The author currently prescribes different behaviour based on whether or not the initPopulation parameter is the same type as an individual or is a dimension higher, and I am trying to replicate this (hence, the Union{T, Vector{T}} in my original response). It would be easy to infer what T should be if Julia Function types could be parameterised by inputs/outputs (because the objfun parameter is a function which takes a T object and returns a float), but I don’t believe this can be done. If I provided a lowerBounds or upperBounds parameter, it would be easy to infer what T should be as this parameter only accepts Vector{T}, but I don’t want to do this. Hence, I would like to explicity specify T when calling the ga function, but I cannot figure out how to do this (I am guessing it’s not possible).

Maybe

foo(a::Union{T, Vector{T}}) where T::Vector{Float64}

The point is that T is supposed to be flexible. The Vector{Float64} from the original post was just an example.

Generally, if you are making a PR to a package, it is best to ask the package authors/maintainers about their preferred style.

That said, rather than go about this in the rather roundabout way you suggest, I would just make initial_population a parameter and let the caller initialize it as they please.

1 Like