This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Type mismatch error when call map() method on a map: case vs function literal

3 replies
BlackFish
Joined: 2012-01-01,
User offline. Last seen 42 years 45 weeks ago.

Hi guys,

I'm reading Programming in Scala and trying some code examples in the
book. There is a code snippet like:
val m = Map("a" -> 1)
m.map { case (k, v) => (k + "!", "x" * v)}
This works. Then I tried to fool around a little bit by changing the
case in the curly braces to a function literal.
m.map((k: String, v: Int) => (k + "!", "x" * v))
Now I get a compiling error:
type mismatch; found : (String, Int) => (String, String)
required: (String, Int) => ?

I don't understand what's the error means. Can anybody tell me why I
can't use function literal here?

I'm using Scala IDE 2.0 on Eclipse 3.7. Scala version is 2.9.1

BlackFish
Joined: 2012-01-01,
User offline. Last seen 42 years 45 weeks ago.
Re: Type mismatch error when call map() method on a map: case vs

I figured it out, the correct way to use function literal here is:
m.map((t: (String, Int)) => (t._1 + "!", "x" * t._2))
Because map() method takes one Tuple2[String, Int] as parameter, not
two parameters(a String and an Int)
I think the error message is a little misleading, though.
On Jan 1, 11:38 am, BlackFish wrote:
> Hi guys,
>
> I'm reading Programming in Scala and trying some code examples in the
> book. There is a code snippet like:
>   val m = Map("a" -> 1)
>   m.map { case (k, v) =>  (k + "!", "x" * v)}
> This works. Then I tried to fool around a little bit by changing the
> case in the curly braces to a function literal.
>   m.map((k: String, v: Int) => (k + "!", "x" * v))
> Now I get a compiling error:
>   type mismatch;  found   : (String, Int) => (String, String)
> required: (String, Int) => ?
>
> I don't understand what's the error means. Can anybody tell me why I
> can't use function literal here?
>
> I'm using Scala IDE 2.0 on Eclipse 3.7. Scala version is 2.9.1

Doug Tangren
Joined: 2009-12-10,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Type mismatch error when call map() method on a map: ca
On Sat, Dec 31, 2011 at 11:12 PM, BlackFish <qshadun [at] gmail [dot] com> wrote:
I figured it out, the correct way to use function literal here is:
 m.map((t: (String, Int)) => (t._1 + "!", "x" * t._2))
Because map() method takes one Tuple2[String, Int] as parameter, not
two parameters(a String and an Int)
I think the error message is a little misleading, though.


When you call map on a Map, a seq of tuples, you are applying a function to equals tuple
{ case (k, v) =>  (k + "!", "x" * v) } is a partial function that is always defined for a 2 item tuple
The `case` keyword here applies the a tuple extractor on the map entires, (k, v)
to get the same effect using a function literal you can use
m.map((t: (String, Int)) => t match { case (k,v) => (k + "!", "x" * v) })
or drop the type annotations, for less verbosity
 m.map(t => t match { case (k, v) => (k + "!", "x" * v) })
or use the _ shorthand, for even less verbosity
m.map(_ match { case (k,v) => (k + "!", "x" * v) })
or the simplest way is just to use the partial function directly, as mentioned above
m.map({ case (k,v) => (k + "!", "x" * v) }) 

BlackFish
Joined: 2012-01-01,
User offline. Last seen 42 years 45 weeks ago.
Re: Type mismatch error when call map() method on a map: case vs

Thanks for your thorough explanation, Doug.

On Jan 1, 12:23 pm, Doug Tangren wrote:
> On Sat, Dec 31, 2011 at 11:12 PM, BlackFish wrote:
> > I figured it out, the correct way to use function literal here is:
> >  m.map((t: (String, Int)) => (t._1 + "!", "x" * t._2))
> > Because map() method takes one Tuple2[String, Int] as parameter, not
> > two parameters(a String and an Int)
> > I think the error message is a little misleading, though.
>
> When you call map on a Map, a seq of tuples, you are applying a function to
> equals tuple
>
> { case (k, v) =>  (k + "!", "x" * v) } is a partial function that is always
> defined for a 2 item tuple
>
> The `case` keyword here applies the a tuple extractor on the map
> entires, (k, v)
>
> to get the same effect using a function literal you can use
>
> m.map((t: (String, Int)) => t match { case (k,v) => (k + "!", "x" * v) })
>
> or drop the type annotations, for less verbosity
>
>  m.map(t => t match { case (k, v) => (k + "!", "x" * v) })
>
> or use the _ shorthand, for even less verbosity
>
> m.map(_ match { case (k,v) => (k + "!", "x" * v) })
>
> or the simplest way is just to use the partial function directly, as
> mentioned above
>
> m.map({ case (k,v) => (k + "!", "x" * v) })

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland