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 
>
>
>

Reply via email to