# How to know what types will the type signature match?

**URL:** <https://discourse.julialang.org/t/how-to-know-what-types-will-the-type-signature-match/25105>\
**Category:** New to Julia\
**Tags:** question, design\
**Created:** [June 10, 2019, 2:29am UTC](https://discourse.julialang.org/t/how-to-know-what-types-will-the-type-signature-match/25105 "2019-06-10T02:29:24Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [June 10, 2019, 2:29am UTC](https://discourse.julialang.org/t/how-to-know-what-types-will-the-type-signature-match/25105/1 "2019-06-10T02:29:24Z")

</div>

When writing some function signatures, I sometimes want to know what types will match them.  
For example,

```julia
f(::AbstractVector{Real}) = 1
f(::AbstractVector{<: Real}) = 2

```

They are quite similar and sometimes could confuse. Is there a way for me to examine what types in the runtime will be sent to `1` and what will be sent to `2`? That’s really great help!

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [June 10, 2019, 3:30am UTC](https://discourse.julialang.org/t/how-to-know-what-types-will-the-type-signature-match/25105/2 "2019-06-10T03:30:28Z")

</div>

is this what you’re looking for?

```julia
julia> f(x::Integer) = x+1
f (generic function with 1 method)

julia> f(x::AbstractFloat) = x+2
f (generic function with 2 methods)

julia> methods(f(0.1))
# 0 methods for generic function "(::Float64)":

julia> methods(f(2))
# 0 methods for generic function "(::Int64)":

```

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [June 10, 2019, 4:00am UTC](https://discourse.julialang.org/t/how-to-know-what-types-will-the-type-signature-match/25105/3 "2019-06-10T04:00:37Z")

</div>

I am afraid not. I do not quite understand what

```julia
julia> methods(f(0.1))
# 0 methods for generic function "(::Float64)":

julia> methods(f(2))
# 0 methods for generic function "(::Int64)":

```

stand for.  
In your example, `methods(f(0.1))` first evaluates `f(0.1)` then evaluates `methods((::Float64))` so I do not see their meaning.  
I actually want to know the set of all types of `x` that can satisfy `f(x::Integer)` (of course it is straightforward in your example). Besides, you are assuming `f`’s output has the same type as the input type, but it is often hard to do that for a general `f` in practice.

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [June 10, 2019, 4:34am UTC](https://discourse.julialang.org/t/how-to-know-what-types-will-the-type-signature-match/25105/4 "2019-06-10T04:34:24Z")

</div>

> [@singularitti](#):
>
> In your example, `methods(f(0.1))` first evaluates `f(0.1)` then evaluates `methods((::Float64))` so I do not see their meaning.

Yes, the examples should probably have read something like:

```julia
julia> methods(f, (Float64,))
# 1 method for generic function "f":
[1] f(x::AbstractFloat) in Main at REPL[3]:1

julia> methods(f, (Int,))
# 1 method for generic function "f":
[1] f(x::Integer) in Main at REPL[2]:1

```

But I think it does not really solve your problem: it tells you which method is used for a particular set of arguments types, rather than telling you the list of all possible argument types for a given method.

* * *

I don’t know how to solve your problem directly, but I would perhaps simplify it to the following one, which might be easier to solve: given a type T, is it possible to list all subtyes of T?

A good start for this simplified question would be to use `subtypes`:

```julia
julia> subtypes(AbstractVector{Real})
10-element Array{Any,1}:
 AbstractRange{Real}                                                                                                                                     
 Base.LogicalIndex{Real,A} where A<:(AbstractArray{Bool,N} where N)                                                                                      
 Base.ReinterpretArray{Real,1,S,A} where A<:AbstractArray{S,1} where S                                                                                   
 Base.ReshapedArray{Real,1,P,MI} where MI<:Tuple{Vararg{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64},N} where N} where P<:AbstractArray
 Core.Compiler.AbstractRange{Real}                                                                                                                       
 DenseArray{Real,1}                                                                                                                                      
 PermutedDimsArray{Real,1,perm,iperm,AA} where AA<:AbstractArray where iperm where perm                                                                  
 SparseArrays.AbstractSparseArray{Real,Ti,1} where Ti                                                                                                    
 SubArray{Real,1,P,I,L} where L where I where P                                                                                                          
 Test.GenericArray{Real,1}                                                                                                                               

```

```julia
julia> subtypes(AbstractVector{<: Real})
14-element Array{Any,1}:
 AbstractRange{T} where T<:Real                                                                                                                                     
 Base.LogicalIndex{T,A} where A<:(AbstractArray{Bool,N} where N) where T<:Real                                                                                      
 Base.ReshapedArray{T,1,P,MI} where MI<:Tuple{Vararg{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64},N} where N} where P<:AbstractArray where T<:Real
 BitArray{1}                                                                                                                                                        
 Core.Compiler.AbstractRange{T} where T<:Real                                                                                                                       
 Core.Compiler.BitArray{1}                                                                                                                                          
 Core.Compiler.LinearIndices{1,R} where R<:Tuple{Core.Compiler.AbstractUnitRange{Int64}}                                                                            
 DenseArray{T,1} where T<:Real                                                                                                                                      
 LinearIndices{1,R} where R<:Tuple{AbstractUnitRange{Int64}}                                                                                                        
 PermutedDimsArray{T,1,perm,iperm,AA} where AA<:AbstractArray where iperm where perm where T<:Real                                                                  
 SparseArrays.AbstractSparseArray{Tv,Ti,1} where Ti where Tv<:Real                                                                                                  
 SubArray{T,1,P,I,L} where L where I where P where T<:Real                                                                                                          
 Test.GenericArray{T,1} where T<:Real                                                                                                                               
 Union{ReinterpretArray{T,1,S,A} where A<:AbstractArray{S,1} where S, ReinterpretArray{T,1,S,A} where A<:AbstractArray{S,1} where S} where T<:Real                  

```

(you could also apply it recursively to replace all abstract types in the list with the list of their own subtypes, but I would tend to think that this would make the list grow qhickly to unmanageable length)

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [June 10, 2019, 5:07am UTC](https://discourse.julialang.org/t/how-to-know-what-types-will-the-type-signature-match/25105/5 "2019-06-10T05:07:45Z")

</div>

> [@ffevotte](#):
>
> AbstractVector{\<: Real}

Thanks, I have thought about this method and had tried some examples. But one thing I do not understand:

```julia
julia> subtypes(Vector{Integer})
0-element Array{Type,1}

julia> subtypes(Vector{<: Integer})
0-element Array{Type,1}

```

They both give an empty array. However,

```julia
julia> subtypes(Integer)
3-element Array{Any,1}:
 Bool    
 Signed  
 Unsigned

julia> Vector{Bool} <: Vector{<: Integer}
true

julia> Vector{Signed} <: Vector{<: Integer}
true

julia> Vector{Unsigned} <: Vector{<: Integer}
true

```

Aren’t `Vector{Bool}`, `Vector{Signed}` and `Vector{Unsigned}` and their subtypes (if exist) the subtypes of `Vector{<: Integer}`? So, is this method incomplete or somewhere I made a mistake?

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [June 10, 2019, 6:42am UTC](https://discourse.julialang.org/t/how-to-know-what-types-will-the-type-signature-match/25105/6 "2019-06-10T06:42:56Z")

</div>

Ah, yes, that makes sense: `T1 <: T2` is true if all values of type `T1` are also of type `T2`. But this does not mean that `T1` has to be a subtype of `T2` (in the sense that the supertype of `T1` would be `T2`): there are many ways that `T1 <: T2` without `T1` and `T2` being related in the type hierarchy.

Besides the examples you gave, I can think of:

```julia
julia> subtypes(Union{Int32, Float32})
0-element Array{Type,1}

julia> Int32 <: Union{Int32, Float32}
true

```

looking only at the type hierarchy, `Int32` has supertype `Signed`, which itself has supertype `Integer`, which itself has supertype `Real` and so on. Nowhere in the hierarchy does `Union{Int32, ...}` appear, yet obviously any `Int32` value `isa Union{Int32, Float32}`.

So you’re right: using `subtypes` is not going to help you with your problem. Hopefully someone more knowledgeable will chime in with another idea…

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [June 10, 2019, 7:04am UTC](https://discourse.julialang.org/t/how-to-know-what-types-will-the-type-signature-match/25105/7 "2019-06-10T07:04:05Z")

</div>

this example can help a little:

```julia
abstract type AbstractExample{T} end

struct ConcreteExample{T} <: AbstractExample{T}
    value::T
end

function test_x(x::AbstractExample{Real})
    return 1
end
function test_x(x::AbstractExample{<:Real})
    return 2
end

a = ConcreteExample{Real}(2) 
#a have the parametric type as Real, not using the dispatch
#a = ConcreteExample{Real}(2) 

b = ConcreteExample(2)
#b is using the type of 2 (Int64)
#b = ConcreteExample{Int64}(2) 

test_x(a) ##1
test_x(b) ##2

```

Real is a container (abstract) type, so only when you create an struct with the type Real, the first function it’s called. in any other case, a concrete implementation will be called, in this case a int64. the Real acts as a union of all subtypes (Integers,Rationals,Floats,etc)  
here are some examples:

```julia
Vector{Real}<:AbstractVector{Real} #true 
Vector{Float64}<:AbstractVector{<:Real} #also true 

```

Edit: added some dank images to try to explain, please correct me if i’m wrong (i ommited some details, like the parameters of ForwardDiff.Dual, but this is what i can deduce)

 ![Diapositiva1](https://global.discourse-cdn.com/julialang/original/3X/e/c/ec54e28624355a1d2b66f0744923f508d3e2f877.png) ![Diapositiva2](https://global.discourse-cdn.com/julialang/original/3X/c/6/c66b257da47efd8376a93e0248619e6df3578e49.png) ![Diapositiva3](https://global.discourse-cdn.com/julialang/original/3X/7/6/761f988a69820e4fe52bf6f5b2c885c6f1b4283c.png) ![Diapositiva4](https://global.discourse-cdn.com/julialang/original/3X/e/5/e5db8063639870c3e786ee3adeb960319001e1b0.png) ![Diapositiva5](https://global.discourse-cdn.com/julialang/original/3X/a/7/a72a9f83aaf3ca8360d5ac4fba93ba9470b69678.png)
