# getting the types right for transformed distributions

#1

I have a question about how to structure certain types. Even though the application is statistics, the question is really about types.

I’d like to build types that take a Distribution (from the Distributions package) and transform it into another Distribution. I’d like this to maintain the VariateForm of the Distribution. Below is a simplified version of what I’d like. Is there a way to do this which works?

using Distributions

type Translation{S,T<:UnivariateDistribution{S}} <: UnivariateDistribution{S}
distribution::T
translation::Float64
scale::Float64
end

Translation( distribution::UnivariateDistribution, x::Float64 ) =
Translation( distribution, x, 1/x )

t = Translation( Normal(), 2.0 )

#2

In general, yes, this is the way to wrap some other object. In the specific example, I am not sure why you have a type parameter `S`, you could just have `T <: UnivariateDistribution` (perhaps you are using `S` somewhere? but that is not in the example).

Also, there is no reason to restrict to `Float64`, use some `R <: Real`, so that your code would work with eg ForwardDiff.jl at zero performance cost.

#3

I think the `S` parameter is necessary so that the resulting type can itself be `<: UnivariateDistribution{S}`.

#4

I must be missing something about the type hierarchy of `Distributions.jl`, but it is unclear to me how that is used. The only parametric usage of that type I could find is the definition, the rest dispatch on `UnivariateDistribution`, and then subtypes just use a non-parametric subtype (eg `Normal`).

#5

I ended up solving my problem soon after posting it. Template parameters were needed for the function:

`
using Distributions

type Translation{S,T<:UnivariateDistribution{S}} <: UnivariateDistribution{S}
distribution::T
translation::Float64
scale::Float64
end

Translation{S,T<:UnivariateDistribution{S}}( distribution::T, x::Float64 ) =
Translation{S,T}( distribution, x, 1/x )

t = Translation( Normal(), 2.0 )
`