typesjuliaparametric-polymorphism

Julia restrict parametric return type


I want to restrict the parametric return type (a Vector of something) of a function.

Say I have a function f defined as follows:

julia> function f()::Vector{Real}
           return [5]
       end
f (generic function with 1 method)

I use Vector{Real} because I don't want to restrict myself too much - the return value might change to [5.0] at some time.

The problem is, that this causes the 5 to be cast to Real - Julia essentially forgets the specific type:

julia> f()
1-element Vector{Real}:
 5

julia> typeof(f())
Vector{Real} (alias for Array{Real, 1})

Note that this is not the case without the parametric type:

julia> function g()::Real
           return 5
       end
g (generic function with 1 method)

julia> g()
5

julia> typeof(g())
Int64

I would've hoped that something like the following would be possible:

julia> function f()::Vector{T} where T<:Real
           return [5]
       end
f (generic function with 1 method)

julia> f()
ERROR: UndefVarError: T not defined
Stacktrace:
 [1] f()
   @ Main ./REPL[7]:2
 [2] top-level scope
   @ REPL[8]:1

However, this only works for parametric types used on parameters:

julia> function f(t::T)::Vector{T} where T<:Real
           return [5]
       end
f (generic function with 2 methods)

julia> f(5)
1-element Vector{Int64}:
 5

This is obviously not what I want. Is there a way to achieve this in Julia?


Solution

  • Try:

    function f()::Vector{<:Real}
        return [5]
    end
    

    And now:

    julia> f()
    1-element Vector{Int64}:
     5