We considered this quite seriously early on and came to the conclusion (which I've only seen confirmed since then) that this is basically equivalent to overloading functions on return type, and that it cannot really be done in dynamically typed languages – at least not in ones that are as polymorphic as Julia. Instead, we decided to take the simple, if sometimes inconvenient, approach that every expression evaluates to the same type of value regardless of the context in which it is evaluated, including literals.
On Mon, Mar 23, 2015 at 4:30 PM, James Fairbanks <[email protected]> wrote: > I know that haskell does this with constants that are polymorphic > functions, but I don't know how it works. > > James Fairbanks > PhD Student > Georgia Tech > > On Mon, Mar 23, 2015 at 11:26 AM, Seth <[email protected]> wrote: > >> Opening a can of worms, here, perhaps, but is there any way to have >> constants assume whatever datatype is reasonable so that converts like this >> aren't necessary? >> >> >> >> On Saturday, March 21, 2015 at 9:07:21 PM UTC-7, James Fairbanks wrote: >>> >>> Glad to help. There is also a function Base.one(T) which is defined to >>> give the multiplicative identity of T which for all subtypes of Real should >>> be the same as convert(T, 1). You aren't really using it as the >>> multiplicative identity though so I am not sure which is better. >>> >>> On Sat, Mar 21, 2015, 11:55 AM Seth <[email protected]> wrote: >>> >>>> Thanks for pointing me in the right direction. I fixed it. It turns out >>>> that when I set the unitrange (using 1:n), the "1" was being interpreted as >>>> Int64, which caused the UnitRange to be Int64, which messed things up. I >>>> now do a convert(T,1) in the construction and everything's good: >>>> >>>> julia> Graph(Int16(5)) >>>> {5, 0} undirected graph >>>> >>>> >>>> On Saturday, March 21, 2015 at 8:37:55 AM UTC-7, Seth wrote: >>>>> >>>>> James, >>>>> >>>>> Thanks. Here's what I get: >>>>> >>>>> julia> Graph(Int16(5)) >>>>> ERROR: MethodError: `convert` has no method matching convert(::Type{ >>>>> UnitRange{Int16}}, ::UnitRange{Int64}) >>>>> This may have arisen from a call to the constructor UnitRange{Int16 >>>>> }(...), >>>>> since type constructors fall back to convert methods. >>>>> Closest candidates are: >>>>> convert{T}(::Type{T}, ::T) >>>>> >>>>> >>>>> >>>>> On Thursday, March 19, 2015 at 2:17:17 PM UTC-7, James Fairbanks wrote: >>>>>> >>>>>> You left out the initialization code for the fields in your excerpt >>>>>> above. What happens when you call Graph(Int16(5))? >>>>>> >>>>>> On Friday, March 6, 2015 at 2:42:20 PM UTC-5, Seth wrote: >>>>>>> >>>>>>> >>>>>>> >>>>>>> I have >>>>>>> >>>>>>> abstract AbstractGraph{T<:Integer} >>>>>>> >>>>>>> type Graph{T}<:AbstractGraph{T} >>>>>>> vertices::UnitRange{T} >>>>>>> edges::Set{Edge{T}} >>>>>>> finclist::Vector{Vector{Edge{T}}} # [src]: ((src,dst), >>>>>>> (src,dst), (src,dst)) >>>>>>> binclist::Vector{Vector{Edge{T}}} # [dst]: ((src,dst), >>>>>>> (src,dst), (src,dst)) >>>>>>> end >>>>>>> >>>>>>> function Graph{T<:Integer}(n::T) >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> and g = Graph(5) works and produces a graph of type Graph{Int64}, >>>>>>> but g = Graph{Int64}(5) produces >>>>>>> >>>>>>> ERROR: MethodError: `convert` has no method matching >>>>>>> convert(::Type{LightGraphs.Graph{Int64}}, ::Int64) >>>>>>> >>>>>>> This is a problem because I have >>>>>>> >>>>>>> function union{T<:AbstractGraph}(g::T, h::T) >>>>>>> gnv = nv(g) >>>>>>> r = T(gnv + nv(h)) >>>>>>> for e in edges(g) >>>>>>> add_edge!(r,e) >>>>>>> end >>>>>>> for e in edges(h) >>>>>>> add_edge!(r, gnv+src(e), gnv+dst(e)) >>>>>>> end >>>>>>> return r >>>>>>> end >>>>>>> >>>>>>> >>>>>>> >>>>>>> Which is failing on line 3 (in the creation of the graph). >>>>>>> >>>>>>> What's the proper way of creating the object from a parameterized >>>>>>> type? Thanks. >>>>>>> >>>>>> >
