>
> 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

Reply via email to