> > Exactly! It's not currently possible to express the > "triangular-dispatch-like" dependency between `C` and `T`, `N`, so you can > just enforce it in the constructors. An ArgumentError here is probably > sensible, but I often find that in cases like these the inner constructor > becomes complicated enough that users always use the more convenient outer > constructors. Just by limiting the signature of your outer constructor, > you effectively end up with MethodErrors.
I wrote this up and discovered the triangular dependency between C,T, and N isn't necessary. I don't know if the following is the right way to do it, but it appears to work. Two questions I have are: 1. Does the constructor extract the type information "the right way"? 2. Can you reduce the amount of code for handling the 1D case? import Base: getindex, setindex!, size using Base.Test immutable SparseArray{T,N,C<:Associative} <: AbstractArray{T,N} data::C dims::NTuple{N,Int} end # outer constructor infers the types from the data you pass # triangular dispatch constraints are always satisfied if you use this constructor # I use the types field here, does that ruin type inference or anything mysteriously bad? function SparseArray(data, dims) nt, t = eltype(data).types n = length(nt.types) C = typeof(data) return SparseArray{t, n, C}(data, dims) end # special case for 1D so you can index by plain integers rather than (Int,) function SparseArray(data, dims::Integer) nt, t = eltype(data).types return SparseArray{t, 1, typeof(data)}(data, (dims,)) end #special 1d case size{T,C<:Associative}(sa::SparseArray{T,1,C}) = sa.dims getindex{T,C<:Associative}(sa::SparseArray{T,1,C}, index::Integer) = sa.data[index] setindex!{T,C<:Associative}(sa::SparseArray{T,1,C}, x, index::Integer) = setindex!(sa.data, x, index) similar{T,C<:Associative}(sa::SparseArray{T,1,C}, ::Type{T}, dims) = SparseArray(Dict{Int, T}(), dims) # satisfying the interface size(sa::SparseArray) = sa.dims getindex(sa::SparseArray, indices...) = sa.data[indices] setindex!(sa::SparseArray, x, indices...) = setindex!(sa.data, x, indices) similar{T}(sa::SparseArray, ::Type{T}, dims) = SparseArray(Dict{typeof(dims), T}(), dims) On Thu, Apr 14, 2016 at 10:57 AM, Matt Bauman <mbau...@gmail.com> wrote: > > Yes, and it was incorporated into Base in 0.5. It's basically a > one-column SparseMatrixCSC. > I just upgraded to 4.5 today. I am getting more and more eager for 0.5-rc1. I implemented the