>
> Though how would one correctly access the 'nth' elements type ?
> It brings up a question regarding parameterized types, how should (or
> should) one access/refer to the parameters of the type rather than an
> instance. It seems like a bad (queezy) practice to dig into the parameters
> of a type?
It's generally bad practice to access fields of objects that aren't
"yours." In the case of the keytype function you defined, for example, it
causes type instability. The more Julian (and type stable way) to define
such a function is:
keytype{K,V}(::Type{Dict{K,V}}) = K
keytype(dict::Dict) = keytype(typeof(dict))
If you *really* need a general, type stable way to access the nth parameter
of a type, your best bet will probably be doing something like this:
@generated function getparam{T,n}(::Type{T}, ::Type{Val{n}})
P = T.parameters[n]
return :($P)
end
Though be warned: naive callers of this method might call it in a type
unstable manner anyway by passing the index "n" from the value domain
rather than the type domain.
Best,
Jarrett
On Thursday, September 3, 2015 at 10:04:22 AM UTC-4, Michael Francis wrote:
>
> I will likely do so, it's quite a common action to take.
>
> Fortunately with typeof( ( 1,2 ) ) == Tuple{Int64,Int64} there is a
> significantly greater consistency in 0.4 vs 0.3
>
> Though how would one correctly access the 'nth' elements type ?
>
> It brings up a question regarding parameterized types, how should (or
> should) one access/refer to the parameters of the type rather than an
> instance. It seems like a bad (queezy) practice to dig into the parameters
> of a type?
>
> On Thursday, September 3, 2015 at 9:41:18 AM UTC-4, Tim Holy wrote:
>>
>> base/dict.jl defines keytype and valtype, but they are not exported. You
>> could
>> file a pull request that exports them (it would be a 2-line patch, though
>> you
>> might want to add a test to make sure they stay exported).
>>
>> --Tim
>>
>> On Thursday, September 03, 2015 06:37:02 AM Michael Francis wrote:
>> > In the short term I have defined the following in the offending package
>> for
>> > v0.4 only
>> >
>> > function keytype( dict )
>> > return eltype( dict ).parameters[1]
>> > end
>> >
>> > I agree that a standard protocol of accessing the key and value types
>> of a
>> > pair / associative is the way to go.
>> >
>> > On Thursday, September 3, 2015 at 9:31:39 AM UTC-4, Matt Bauman wrote:
>> > > Oh man that's tricky. The trouble is that you're effectively saying
>> > > `Pair{Symbol,Int}[1]`, which is the syntax for a typed array:
>> > > Pair{Symbol,Int}[:x=>1, :y=>2]. One way around this is to define:
>> > >
>> > > keytype{A,B}(::Type{Pair{A,B}}) = A
>> > > valuetype{A,B}(::Type{Pair{A,B}}) = B
>> > > pairtypes{A,B}(::Type{Pair{A,B}}) = (A,B)
>> > >
>> > > If you need this to work on 0.3, too, you can easily make these
>> functions
>> > > work for the old-style Tuples, too.
>> > >
>> > > On Thursday, September 3, 2015 at 9:06:30 AM UTC-4, Michael Francis
>> wrote:
>> > >> Incidentally
>> > >>
>> > >> eltype( Pair{String,Float64} )
>> > >>
>> > >> gives Any, that seems slightly strange as well .
>> > >>
>> > >> On Thursday, September 3, 2015 at 9:02:33 AM UTC-4, Michael Francis
>> wrote:
>> > >>> julia> eltype( Dict( :x => 1, :y => 2 ) )[1]
>> > >>> ERROR: MethodError: `convert` has no method matching
>> convert(::Type{Pair
>> > >>> {Symbol,Int64}}, ::Int64)
>> > >>> This may have arisen from a call to the constructor
>> Pair{Symbol,Int64
>> > >>> }(...),
>> > >>> since type constructors fall back to convert methods.
>> > >>>
>> > >>> Closest candidates are:
>> > >>> Pair{A,B}(::Any, ::Any)
>> > >>> call{T}(::Type{T}, ::Any)
>> > >>> convert{T}(::Type{T}, ::T)
>> > >>>
>> > >>> in getindex at array.jl:167
>> > >>>
>> > >>> Is this intentional ? This breaks a package I am dependent on - I
>> > >>> believe the assumption was that Pair would respect the tuple API,
>> this
>> > >>> appears to not be the case ?
>> > >>>
>> > >>> collect( eltype( Dict( :x => 1, :y => 2 ) ) )
>> > >>> ERROR: MethodError: `start` has no method matching
>> start(::Type{Pair{
>> > >>> Symbol,Int64}})
>> > >>>
>> > >>> in collect at array.jl:255
>> > >>> in collect at array.jl:262
>>
>>