Thanks Tim! That was really helpful, especially the trick with adding an extra layer of functions with a different name.
On Saturday, July 9, 2016 at 2:56:49 AM UTC-7, Tim Holy wrote: > > Ambiguities are often a bit tricky. Two tips I've adopted: > > - Have as few methods as possible, and declare types on their arguments > only > when absolutely necessary. These measures greatly reduce your exposure to > the > risk of ambiguities. To achieve this, it sometimes takes a fair bit of > thought > to design your API. > > - Use one layer of indirection per argument you want to specialize. There > are > a couple of ways to pull this off, and the best way to do it usually > depends > on the specific goal you're trying to achieve. But here one approach might > be > to decide that `f` will only be specialized on argument 2, and will > otherwise > dispatch to `f1` (which you can specialize for argument 1). > > f(a, b) = f1(a, b) > f(a, b::A) = "from A" > f1(a::Int, b) = "Int" > f1(a, b) = "other" > > Best, > --Tim > > On Friday, July 8, 2016 8:27:30 PM CDT Darwin Darakananda wrote: > > Is there a recommended way to getting around that? The example above > had a > > union of only two types, but in the actual code I'm working on there are > a > > couple more. Would I have to copying the code over and over with just > > small changes to the type signature? I guess you could use a macro to > > splice the types in. > > > > On Friday, July 8, 2016 at 7:58:02 PM UTC-7, Yichao Yu wrote: > > > On Fri, Jul 8, 2016 at 10:32 PM, Darwin Darakananda > > > > > > <[email protected] <javascript:>> wrote: > > > > Hi everyone, > > > > > > > > I have some code where multiple types share the same implementation > of a > > > > method, for example: > > > > > > > > abstract MyType > > > > > > > > > > > > type A <: MyType end > > > > type B <: MyType end > > > > > > > > > > > > f(target::MyType, source::MyType) = "fallback" > > > > > > > > > > > > f(target::Int, source::A) = "from A" > > > > f(target::MyType, source::A) = "from A" > > > > > > > > a = A() > > > > b = B() > > > > > > > > f(b, b) # fallback > > > > f(b, a) # from A > > > > f(a, a) # from A > > > > > > > > I was hoping that I could replace the "from A" function using a > union > > > > > > type, > > > > > > > but I'm running into ambiguity errors: > > > > > > > > f(target::Union{Int, MyType}, source::A) = "from A" > > > > > > > > f(b, b) # fallback > > > > f(b, a) # Ambiguity error > > > > f(a, a) # Ambiguity error > > > > > > > > Is this an expected behavior? > > > > > > Yes. > > > > > > > I thought that (::Union{Int, MyType}, ::A) > > > > would be a more specific match to (::B, ::A) than (::MyType, > ::MyType). > > > > > > There's basically nothing as a "more specific match". The two methods > > > are ambiguous and anything in their intersection cannot be dispatched > > > to either of them. > > > > > > > Any ideas/suggestions? > > > > > > > > Thanks, > > > > > > > > Darwin > > >
