3

Here is a code snippet that tries to reproduce a problem I am facing while implementing an internal DSL:

object testObj {
    implicit def foo1[T <% Function1[Int, Int]](fun: T): String = "foo1"
    implicit def foo2[T <% Function2[Int, Int, Int]](fun: T): String = "foo2"

    def test(arg: String): Unit = {}

    test((x:Int) => 5) //Ambiguous implicit conversion error
    test((x:Int, y:Int) => 5) //Ambiguous implicit conversion error
}

I am getting ambiguous implicit conversions errors at the shown locations:

<console>:21: error: type mismatch;
 found   : Int => Int
 required: String
Note that implicit conversions are not applicable because they are ambiguous:
 both method foo1 in object testObj of type [T](fun: T)(implicit evidence$1: T => (Int => Int))String
 and method foo2 in object testObj of type [T](fun: T)(implicit evidence$2: T => ((Int, Int) => Int))String
 are possible conversion functions from Int => Int to String
           test((x:Int) => 5) //Ambiguous implicit conversion error
                        ^

However commenting one of the implicits does not solve the problem. I am using view bounds since finally I want to chain the implicits. Note that the code snippet given above does not involve implicit chaining.

I was expecting that foo1 implicit conversion would be applicable for the first test application whereas foo2 implicit conversion would be applicable for the second test application. I don't understand how both the implicits are applicable to both the testfunction applications. Why is this happening and how to make this work?

Edit: If I don't use view bounds, it works fine as shown below. But I want to use view bounds since I want to chain the implicits the way it is explained in the post How can I chain implicits in Scala?.

implicit def foo1(fun: Function1[Int, Int]): String = "foo1"
implicit def foo2(fun: Function2[Int, Int, Int]): String = "foo2"

def test(arg: String): Unit = {}
test((x:Int) => 5) //No error
test((x:Int, y:Int) => 5) //No error
Community
  • 1
  • 1
dips
  • 1,627
  • 14
  • 25
  • I don't understand what you want to achieve. Could you please elaborate how the code should be interpreted in an explicit way? – kiritsuku Jul 29 '12 at 09:56
  • I know it is hard to understand what the code is doing...I have simplified it too much to render it useless...But the full code involves too many dependencies that I find it hard to mention here. I have edited the post to include an example without view bounds which works. But the reason I want to use view bounds is to chain implicits as explained the edit. – dips Jul 29 '12 at 11:43
  • What do you want to chain? Do you want to call both implicits at once? What should be the output (or better which implicits should be called) when you call `test` with a function? – kiritsuku Jul 29 '12 at 11:50
  • @sschaef for the first `test` call, `foo1` should be called and for the second `test` call, `foo2` should be called. (this works fine if I don't use the view bounds. ) – dips Jul 29 '12 at 12:12
  • Yes, but this doesn't explain what you want to fill in for the view bound. If you call the implicits explicitly as `test(foo1((x:Int)=>5)(???))` what should `???` be? – kiritsuku Jul 29 '12 at 12:46
  • @sschaef the ??? would be `identity` function. Please refer the `T2Translated` object in the post [How can chain implicits in scala](http://stackoverflow.com/questions/5332801/how-can-i-chain-implicits-in-scala) – dips Jul 30 '12 at 04:38
  • Ok, now I understand how your question is meant. But I'm afraid I can't answer it. – kiritsuku Jul 30 '12 at 09:06
  • @dips If you want to form arbitrarily long chains of implicits, see [my question here](http://stackoverflow.com/questions/11481760/safely-chaining-implicit-conversions). I can't promise it will work in your case, though (or in any case, actually). – Ptharien's Flame Jul 30 '12 at 17:54

1 Answers1

0

I'm afraid this won't work. View bounds are just not taken into account when resolving implicits and thus you can't chain implicits. That is be design, because such chaining could create some very unreadable code. The only option I see is to create a new implicit conversion for each possible chain of conversions.

Kim Stebel
  • 41,826
  • 12
  • 125
  • 142
  • The post [how-can-i-chain-implicits-in-scala](http://stackoverflow.com/questions/5332801/how-can-i-chain-implicits-in-scala) makes me believe that the view bounds are taken into account when resolving implicits. – dips Jul 29 '12 at 11:36