Hi Neal,
It is not good practice to leave out parts of the template that Dan offers.
While it may work with some test data, it is very likely to fail in
general use (particularly by/with use from other packages) and it may
become incompatible in some specific manner with future releases.
If I get your drift, something like this may serve
underlyingtype{T}(::Type{Complex{T}}) = T
type ComplexOf{S,T}
sum::S
sumsqr::T
function ComplexOf{S,T}(s::S,ss::T)
realtype = underlyingtype(S)
if typeof(ss) != realtype
throw(
TypeError( :ComplexOf, "ComplexOf($s,$ss)\n\t\t", realtype, T
))
end
new(s,ss)
end
end
ComplexOf{S,T}(x::S, y::T) = ComplexOf{S,T}(x,y)
ComplexOf(1.5+2.0im, 1.0)
ComplexOf(5+2im, 3)
# force a type error by mixing the kinds of underlying types
ComplexOf(5.0+1.5im, 2.0f0)
# presumably, you want to add
function ComplexOf{T}(x::Vector{Complex{T}})
s = sum(x)
ss = abs2(s)
return ComplexOf(s,ss)
end
test = ComplexOf([3.0+1.0im, 2.0-1.0im]);
test.sum, test.sumsqr
If you have questions about why something is present, do ask.
Also, in this case, you can use `immutable ComplexOf` rather than `type
ComplexOf`, which helps if there are very many of them.
On Thursday, September 15, 2016 at 8:44:28 AM UTC-4, Neal Becker wrote:
>
> OK, I think I got it:
>
> decomplexify{T}(::Type{Complex{T}}) = T
>
> type var2{T,S}
> sum::S
> sumsqr::T
> nobjs::Int64
> var2() = new(0,0,0)
> end
>
> (::Type{var2{T}}){T}() = var2{T,decomplexify((T))}() << magic?
> var2() = var2{Complex{Float64},Float64}() << default
>
> This seems to work
> Problem is I have no idea what this line marked "magic" means.
>
> Isaiah Norton wrote:
>
> > See
> https://github.com/JuliaLang/julia/issues/18466#issuecomment-246713799
> >
> > On Wed, Sep 14, 2016 at 6:13 PM, Dan
> > <[email protected] <javascript:>> wrote:
> >
> >> Maybe the following is the form you are looking for:
> >>
> >> julia> decomplexify{T}(::Type{Complex{T}}) = T
> >> decomplexify (generic function with 1 method)
> >>
> >>
> >> julia> type bar{S,T}
> >> sum::S
> >> sumsqr::T
> >> function bar(s,ss)
> >> if typeof(ss) != decomplexify(typeof(s))
> >> error("Yaiks")
> >> end
> >> new(s,ss)
> >> end
> >> end
> >>
> >>
> >> julia> bar{Complex{Float64},Float64}(1.5+2.0im,1.0)
> >> bar{Complex{Float64},Float64}(1.5 + 2.0im,1.0)
> >>
> >>
> >> julia> bar{S,T}(x::S,y::T) = bar{S,T}(x,y)
> >> bar{S,T}
> >>
> >>
> >> julia> bar(1.5+2.0im,1.0)
> >> bar{Complex{Float64},Float64}(1.5 + 2.0im,1.0)
> >>
> >>
> >> The outer constructor is necessary to get the last line working. The
> >> inner constructor basically maintains the constraint between S and T
> of:
> >> T == Complex{S}.
> >>
> >> On Wednesday, September 14, 2016 at 3:38:53 PM UTC-4, Neal Becker
> wrote:
> >>>
> >>> Evan Fields wrote:
> >>>
> >>> > How about something like the following?
> >>> >
> >>> > type CT{T}
> >>> > ctsum::Complex{T}
> >>> > ctsumsq::T
> >>> > end
> >>> >
> >>>
> >>> I'm aware that it's easier to make the type parameter the scalar type,
> >>> allowing writing as you show, but as a learning exercise I'd like to
> >>> know how Julia would go the other way.
> >>>
> >>> In c++ this would be done with template metaprogramming, but as Julia
> >>> claims
> >>> to have types as 1st class objects, I thought there should be some
> >>> elegant
> >>> way to do this.
> >>>
> >>> That is, given T is Complex{U}, I need the type U so I can write
> >>> ctsumsq::U
> >>>
> >>>
>
>
>