Skip to content

Instantly share code, notes, and snippets.

@Jutho
Last active December 29, 2015 14:29
Show Gist options
  • Save Jutho/7684732 to your computer and use it in GitHub Desktop.
Save Jutho/7684732 to your computer and use it in GitHub Desktop.
Code to illustrate type inference issue
import Base: one, eltype
typealias AbstractNumericalMatrix{T<:Number} AbstractMatrix{T}
specialsum{T<:Number}(a1::Matrix{T},a2::Matrix{T})=a1+a2
type MatrixList{T<:Number,A<:AbstractNumericalMatrix} # T should correspond to the eltype of A
list::Vector{A}
args
# Note that we cannot add a constructor MatrixList{T}(list::Vector{AbstractMatrix{T}})
# since Vector{A} for some A<:AbstractMatrix{T} is not a subtype of Vector{AbstractMatrix{T}}
# so I think the only option is doing the eltype checking manually
function MatrixList(list::Vector{A},args...)
if eltype(A)!=T
throw(ArgumentError("Wrong eltype in matrix list"))
end
new(list,args)
end
end
MatrixList{A<:AbstractNumericalMatrix}(list::Vector{A},args...) = MatrixList{eltype(A),A}(list,args...)
#MatrixList{T<:Number}(a::Matrix{T},b::Matrix{T}) = MatrixList{T,Matrix{T}}(Matrix{T}[a,b])
eltype{T<:Number}(m::MatrixList{T})=T
one(m::MatrixList)=MatrixList(map(one,m.list))
*(m::MatrixList,x::Number)=MatrixList([x*a for a in m.list])
*(x::Number,m::MatrixList)=MatrixList([x*a for a in m.list])
function +(m1::MatrixList,m2::MatrixList)
a=specialsum(m1.list[1],m2.list[1])
list=Array(typeof(a),length(m1.list))
list[1]=a
for i=2:length(m1.list)
list[i]=specialsum(m1.list[i],m2.list[i])
end
return MatrixList(list)
end
+(m1::MatrixList,x::Number)=+(m1,x*one(m1))
# Example code:
m1=MatrixList([rand(3,3) for i=1:5])
m2=MatrixList([rand(3,3) for i=1:5])
# all of this works:
one(m1)
m1+m2
3*m1
# this produces Nothing:
m1+3
# Note that adding explicit annotation: +(m1::MatrixList,x::Number)=+(m1,x*one(m1))::MatrixList
# results in a bug:
# ERROR: type: typeassert: expected MatrixList{T<:Number,A<:AbstractArray{T<:Number,2}}, got (MatrixList{Float64,Array{Float64,2}},MatrixList{Float64,Array{Float64,2}})
# in +
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment