Ah, that was obvious. Example of why late night coding isn't very productive :) Thanks!
On Monday, October 12, 2015 at 2:15:02 AM UTC+3, Yichao Yu wrote: > > On Sun, Oct 11, 2015 at 6:54 PM, Andrei Zh <[email protected] > <javascript:>> wrote: > > I didn't know about such capability, thanks. But I still can't figure > out > > how to call this constructor. E.g.: > > > > julia> Bar{Int}() > > ERROR: MethodError: `convert` has no method matching > > convert(::Type{Bar{Int64}}) > > This may have arisen from a call to the constructor Bar{Int64}(...), > > since type constructors fall back to convert methods. > > Closest candidates are: > > convert{T}(::Type{T}, !Matched::T) > > Bar{#s6,T}() > > call{T}(::Type{T}, !Matched::Any) > > in call at essentials.jl:57 > > > > Don't know if it matters, but I also have a different output of > > `methods(Bar{Int})` than you: > > > > julia> methods(Bar{Int}) > > 3-element Array{Any,1}: > > call{#s6,T}(::Type{Bar{#s6}}) at > > /home/<username>/work/playground/contructors.jl:11 > > call{T}(::Type{T}, arg) at essentials.jl:56 > > call{T}(::Type{T}, args...) at essentials.jl:57 > > > > The error I get (which seems to be different from yours) is > > ``` > julia> type Bar{T} > x::Array{T,1} > Bar() = Bar(zeros(T, 10)) > end > > julia> Bar{Int}() > ERROR: MethodError: `convert` has no method matching > convert(::Type{Bar{T}}, ::Array{Int64,1}) > This may have arisen from a call to the constructor Bar{T}(...), > since type constructors fall back to convert methods. > Closest candidates are: > call{T}(::Type{T}, ::Any) > convert{T}(::Type{T}, ::T) > in call at ./none:3 > ``` > > And the issue here is that you cannot call the non-existing default > inner constructor if you provide your own one. I suspect `Foo()` won't > work for you either. > > The following works for me > > ``` > julia> type Bar{T} > x::Array{T,1} > Bar() = new(zeros(T, 10)) > end > > julia> Bar{Int}() > Bar{Int64}([0,0,0,0,0,0,0,0,0,0]) > ``` > > > > > > > > > > > On Monday, October 12, 2015 at 1:06:14 AM UTC+3, Yichao Yu wrote: > >> > >> On Sun, Oct 11, 2015 at 5:57 PM, Andrei Zh <[email protected]> > wrote: > >> > Let's consider 2 types with inner constructors: > >> > > >> > type Foo > >> > x::Array{Int,1} > >> > > >> > > >> > Foo() = Foo(zeros(Int, 10)) > >> > end > >> > > >> > type Bar{T} > >> > x::Array{T,1} > >> > > >> > > >> > Bar() = Bar(zeros(T, 10)) > >> > end > >> > > >> > The only difference between them is that `Bar` has type parameter > while > >> > `Foo` doesn't. I'd expect their inner constructors behave the same > way, > >> > but > >> > `Bar` turns to ignore inner constructor definition: > >> > > >> > julia> methods(Foo) > >> > 3-element Array{Any,1}: > >> > call(::Type{Foo}) at > /home/<username>/work/playground/contructors.jl:5 > >> > call{T}(::Type{T}, arg) at essentials.jl:56 > >> > call{T}(::Type{T}, args...) at essentials.jl:57 > >> > > >> > > >> > julia> methods(Bar) > >> > 2-element Array{Any,1}: > >> > call{T}(::Type{T}, arg) at essentials.jl:56 > >> > call{T}(::Type{T}, args...) at essentials.jl:57 > >> > > >> > Is it a bug or a feature and how to make `Bar` recognize inner > >> > constructor > >> > (outer constructor is not an option here since it uses type parameter > >> > `T` in > >> > constructor body, but not in its constructor)? > >> > > >> > >> As you pointed out, the inner constructor can access the type > >> parameter and therefore the type parameter needs to be specified in > >> order to call it. > >> > >> julia> methods(Bar{Int}) > >> 3-element Array{Any,1}: > >> call{T}(::Type{Bar{T}}) at none:3 > >> call{T}(::Type{T}, arg) at essentials.jl:55 > >> call{T}(::Type{T}, args...) at essentials.jl:56 >
