and if you're pretty happy, that's all!
On Thursday, September 15, 2016 at 10:43:09 AM UTC-4, Neal Becker wrote: > > After some iterations, I'm pretty happy with this form, which doesn't need > any magic: > > https://gist.github.com/nbecker/58f79e449400159e4762f6c8eedd9f65 > > The type var is parameterized by 2 parameters, and the constructors take > care of the type computations, similar to Dan's suggestion. The invariant > checking you suggest could be added (but in my case would be a bit more > complicated) > > Jeffrey Sarnoff wrote: > > > 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 > >> >>> > >> >>> > >> > >> > >> > > >
