Generic types in parametric struct constructor

Why does this not work ?

using Distributions
Uniform{Float32}(0.0,1.0)
ERROR: MethodError: no method matching Uniform{Float32}(::Float64, ::Float64)
Closest candidates are:
  Uniform{Float32}(::T<:Real, ::T<:Real) where T<:Real at /home/dehaybe/.julia/packages/Distributions/tfkz4/src/univariate/continuous/uniform.jl:29
Stacktrace:
 [1] top-level scope at none:0

I’m not looking for a fix here but I’d like to know why my Float64 arguments are not considered as subtypes of Real and why the closest candidate is not used.

The actual candidate is:

Uniform{T}(a::T, b::T) where {T <: Real} = new{T}(a, b)

from here: https://github.com/JuliaStats/Distributions.jl/blob/a2304a8811f42a7203c76950ddf5f3a5bceb4533/src/univariate/continuous/uniform.jl#L29 (assuming your Distributions.jl is the same as master). That signature requires that the type in {T} be the same as the types of a and b, so you would want something like:

Uniform{Float32}(Float32(0.0), Float32(1.0))

It would be easy for Distributions.jl to add an additional inner constructor (or just replace the existing one) to make your original code work as intended:

Uniform{T}(a, b) where {T} = new{T}(a, b)

And I agree that the way Julia prints that method mismatch error is awkward. Is this on the latest version of Julia?

Thank you :slight_smile:

Yes it’s Julia 1.2.0.