2

I wrote this code

case class Foo(x: Int) case class Bar(y: Int) object Foo { implicit def toBar(f: Foo) : Bar = { Bar(f.x) } implicit def toBarList(fl: List[Foo]) : List[Bar] = {fl.map{x: Bar => x}} 

The toBarList function doesn't compile.

<console>:17: error: type mismatch; found : Bar => Bar required: Foo => ? implicit def toBarList(fl : List[Foo]) : List[Bar] = { fl.map{x : Bar => x}} 

However shouldn't the implicits system kick in here? meaning that compiler should detect that there is an error that the function expects a Bar but I am passing a Foo. Now there is already a implicit function in scope which converts Foo to a Bar, so that should be used and things should work.

So why did this not compile?

1
  • In first snippet, {fl.map{x: Bar => b}}, probably you meant {fl.map{x: Bar => x}} or {fl.map{b: Bar => b}}. Commented Sep 22, 2016 at 14:31

1 Answer 1

2

map is an ordinary method that takes a function argument, and map on a List[Foo] requires a function from Foo. You've provided an function from Bar—specifically Bar => Bar—but having an implicit conversion from Foo to Bar doesn't mean you have one from Bar => Bar to Foo => Bar (which is what the method needs).

If you want this to work you'll either need to provide a function from Foo and then apply the conversion (either explicitly or implicitly), or you'll need to provide an implicit conversion from Bar => Bar to Foo => Bar (similar to the one you're trying to provide from List[Foo] to List[Bar], but with the conversion happening in the other direction, since Function1 is contravariant in its first argument while List is covariant).

(This is all a very bad idea, though.)

Sign up to request clarification or add additional context in comments.

2 Comments

pardon my ignorance. but when the compiler found that I have provided Foo => Bar but it needed Bar => Bar. Why didn't it look for an implicit and automagically put the Foo to Bar conversion there? therefore the compiler should convert my Foo => Bar conversion to Bar => Bar conversion because I have a Foo => Bar conversion in scope.
@KnowsNotMuch The core of the reason is that functions are just instances of a particular class (that happens to have some special syntax). There's no special-casing in this respect—if you need a Foo => Bar and have a Bar => Bar, the Foo-to-Bar conversion won't help you (just like it won't help you if you have a List[Foo] and need a List[Bar]).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.