Dispatch on both parametrized and non-parametrized type

#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.