However, trying out the supposed fix yields the following error:
RealLowerTriangular(ones(2))
ERROR: MethodError: Cannot convert an object of type Array{Float64,1} to an object of type LowerTriangular{T,S} where S<:(AbstractArray{T,2} where T) where T<:Real
This may have arisen from a call to the constructor LowerTriangular{T,S} where S<:(AbstractArray{T,2} where T) where T<:Real(…),
since type constructors fall back to convert methods.
Stacktrace:
[1] LowerTriangular{T,S} where S<:(AbstractArray{T,2} where T) where T<:Real(::Array{Float64,1}) at ./sysimg.jl:24
julia> typealias RealLowerTriangular{T<:Real, S<:AbstractMatrix} LowerTriangular{T, S}
LowerTriangular{T<:Real,S<:AbstractArray{T,2}}
julia> RealLowerTriangular(ones(2))
ERROR: MethodError: Cannot `convert` an object of type Array{Float64,1} to an object of type LowerTriangular{T<:Real,S<:AbstractArray{T,2}}
This may have arisen from a call to the constructor LowerTriangular{T<:Real,S<:AbstractArray{T,2}}(...),
since type constructors fall back to convert methods.
in LowerTriangular{T<:Real,S<:AbstractArray{T,2}}(::Array{Float64,1}) at ./sysimg.jl:53
Thanks Dan, this wasn’t meant to be an accurate example, you are right that ones(2, 2) is not lower triangular. What I am getting at is that the equivalent proposed by Julia v0.6 no longer works, one could use for instance eye(2) above instead of ones(2, 2) to make this point.
Indeed there is a problem getting to the constructor of LowerTriangular from the typedef-ed RealLowerTriangular. A solution can be to define the outer constructor:
# first we do the typedef
RealLowerTriangular{T,S} = LowerTriangular{T,S} where {T<:Real,S<:AbstractMatrix{T}}
# now the outer constructor
RealLowerTriangular(m) = LowerTriangular(m)
The logic is as follows: Calling a constructor is basically calling a method with the type as its name. The outer constructor LowerTriangular is simply a method named LowerTriangular{T,S} where S where T. A RealLowerTriangular is defined as LowerTriangular{T,S} where S<:AbstractMatrix{T} where T<:Real so Julia doesn’t find a method with this name and defaults to the convert constructor for a generic type.
In general, the non-parametrized names of parametric types are equivalent to the types with appropriate where T clauses added (for each parameter).