Dispatch on both parametrized and non-parametrized type

question

#1

I would like to write a function that returns something for each type it is defined for. Importantly,

  1. it needs to dispatch on types, not instances, since I need the result before I create the latter,
  2. it would be nice if it worked on parametric types, giving the same result regardless of the parameters.

An MWE is

immutable Foo{T} x::T end

transformation(::Type{Foo}) = :standard
transformation{T}(::Type{Foo{T}}) = :standard

and my problem is that I have to define both for Foo and Foo{T} because of invariance (if I understand correctly). This becomes cumbersome if the type has more parameters.

Is there a way to define it once, and have it work for Foo and eg Foo{Float64}?


#2
transformation{T<:Foo}(::Type{T}) = :standard

?


#3

Thanks, I overlooked this.

Can someone explain why

julia> immutable Foo{T} x::T end

julia> Foo <: Foo{Int}
false

julia> Foo{Int} <: Foo
true

but

julia> supertype(Foo{Int})
Any

that is to say, if A <: B and !(B <: A), I would expect to find B among the supertypes of A somewhere along the chain. Apparently I have the wrong intuition.


#4

that is to say, if A <: B and !(B <: A), I would expect to find B among the supertypes of A somewhere along the chain. Apparently I have the wrong intuition.

There’s an infinite number of supertypes. The one returned by supertype is simply one choice. Consider, for example, what the shape of the type-tree of a parameterized type must look like:

julia> immutable Foo{T} <: Abstract{T} end

Here we have that Foo{T} <: Abstract{T}, Foo{T} <: Foo, Foo <: Abstract, and Abstract{T} <: Abstract. All of these are supertypes, but you cannot arrange them linearly.
To get the infinite set, you have to add in the consideration that a larger type can also be formed by taking the union of the type with any other type, or by widening any of the type-variables.

The supertype Foo{T} <: Foo would be formed by widening the type-variables from T to (one of) its supertype. The supertype function is instead formed as a widening of the base type.


#5

Thanks, the example was really enlightening.