BlackFish | 1 Jan 2012 04:38
Picon

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

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 | 1 Jan 2012 05:12
Picon

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

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 <qsha...@...> 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 | 1 Jan 2012 05:23
Picon
Gravatar

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

On Sat, Dec 31, 2011 at 11:12 PM, BlackFish <qshadun-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 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 | 1 Jan 2012 06:32
Picon

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

Thanks for your thorough explanation,  Doug.

On Jan 1, 12:23 pm, Doug Tangren <d.tang...@...> wrote:
> On Sat, Dec 31, 2011 at 11:12 PM, BlackFish <qsha...@...> 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) })

Rex Kerr | 1 Jan 2012 07:06
Picon
Gravatar

Re: Re: How to avoid Int and Double boxing in a returned tuple ?

You're benchmarking wrong if you find that case classes are _slower_ than tuples.  (Unless there is some other source of boxing/unboxing and you're actually making it worse by storing primitives in case classes.)

  --Rex

On Sat, Dec 31, 2011 at 8:38 AM, guast <v.guast-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
Thanks for the answer.

I tried again, but eventually to avoid the forced boxing I created my
own box and it was even slower.

On Dec 31, 1:16 pm, Rex Kerr <icho...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> The specialized version should work (you were probably not looking at the
> SpecializedTuple3$mcIDD$sp class which is the specialized version that is
> generated and will be used if all the parameters match), but it's overkill
> for your application.  Just use a case class--and then you can name your
> variables something sensible also!
>
>   case class MbIter(i: Int, x: Double, y: Double) {}
>   ...
>     else MbIter(iterations, x, y)
>   ...
>
>   --Rex
>
>
>
>
>
>
>
> On Sat, Dec 31, 2011 at 6:16 AM, guast <v.gu...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> > Hi All
>
> > I have a method that returns a tuple of (Int, Double, Double). I am
> > returning some fields of the same type. However in the generated class
> > I can see that the value are boxed. That method will be called
> > millions of times so I am trying to optimize it as much as possible,
> > but I can't avoid the boxing. Is there a way to do it ?
>
> > This is the last version of the method:
>
> > private def getIterations(x:Double, y:Double, x_0:Double,
> >                          y_0:Double, iterations: Int):(Int, Double,
> > Double) = {
> >  if (iterations < maxIterations && x*x + y*y <= 4)
> >      getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0,
> > iterations+1)
> >  else (iterations, x, y)
> > }
>
> > This is the generated code:
> > final def mandelbrotsetdesigner$FunctionIterator$$getIterations(x:
> > Double, y: Double, x_0: Double, y_0: Double, iterations: Int): Tuple3
> > = {
> >  <synthetic> val _$this: mandelbrotsetdesigner.FunctionIterator =
> > FunctionIterator.this;
> >  _getIterations(_$this,x,y,x_0,y_0,iterations){
> >    if (iterations.<(FunctionIterator.this.maxIterations()).&&(x.*(x).+
> > (y.*(y)).<=(4)))
> >      _getIterations(FunctionIterator.this, x.*(x).-(y.*(y)).+(x_0),
> > x.*(y).*(2.0).+(y_0), x_0, y_0, iterations.+(1))
> >    else
> >      new Tuple3(scala.Int.box(iterations), scala.Double.box(x),
> > scala.Double.box(y))
> >  }
> > };
>
> > ----------------------------------------------------
> > I tried this way as well, but it didn't work
>
> > case class SpecializedTupleT3 [ <at> specialized(Int) TT1,
> >                                               <at> specialized(Double)
> > TT2,
> >                                               <at> specialized(Double)
> > TT3](_1:TT1, _2:TT2, _3:TT3)
> > private def getIterations(x:Double, y:Double, x_0:Double,
> >                          y_0:Double, iterations:
> > Int):SpecializedTupleT3[Int, Double,
> > Double] = {
> >  if (iterations < maxIterations && x*x + y*y <= 4)
> >    getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0, iterations
> > +1)
> >  else new SpecializedTupleT3[Int, Double, Double](iterations, x, y)
> > }
>
> > -------------
>
> > Thanks

Sonnenschein | 1 Jan 2012 13:28
Picon
Favicon

Re: Immutable graph libraries and alternative structures

Hi Tim,

>I know there has been more than one go at writing graph libraries.
Do you mean Scala graph libraries? As I began work on Graph4Scala
roughly one year ago, EPFL backed the idea of my contribution because
there was no general purpose Scala alternative.

>… I need immutable graph structures of fairly modest size (a few hundred to about 4000 nodes)… they are
typically highly  disconnected… The graphs are also directed and not cyclic. So I'm looking for a
library that will support that sort of structure
efficiently and immutably - though I'm not unhappy doing one by hand.

Graph4Scala does meet your above requirements. If you wanted even
automatic maintenance of acyclicity for your graph instances you could
rely on this feature of the next Graph4Scala release. But I assume
that’s not your point.

Certainly you may have a lot of other, including non-technical reasons
to prefer an individual implementation(?).

If you still considered Graph4Scala, the next step would be to make
thoughts about how to integrate your algorithms and which node/edge
layout to select to achieve an optimal solution with minimal efforts.

Peter

Tim P | 1 Jan 2012 15:10
Favicon
Gravatar

Reflection

Hi
I want to use reflection to generate case classes from XML.
Any recommendations for a reflection tool for the job?
Can't use 2.10 nightly builds and new API because of coordination with
other libraries.

Tim

Donald McLean | 1 Jan 2012 15:20
Picon
Gravatar

Re: Reflection

What's wrong with Class.forName? It has the virtue of simplicity, even
if it isn't necessarily the prettiest call in the standard library.

Donald

On Sun, Jan 1, 2012 at 9:10 AM, Tim P <tim.pigden@...> wrote:
> Hi
> I want to use reflection to generate case classes from XML.
> Any recommendations for a reflection tool for the job?
> Can't use 2.10 nightly builds and new API because of coordination with
> other libraries.

urbanc | 1 Jan 2012 15:32

REPL question

Hi,

I am often writing small scala programs using Emacs and the REPL.
However, whenever
I define something like

abstract class Rexp {
  def ~ (right : Rexp) = SEQ(this, right)
  def || (right : Rexp) = ALT(this, right)
  def ** = STAR(this)
}

case object NULL extends Rexp
case object EMPTY extends Rexp
case class CHAR(c: Char) extends Rexp
case class ALT(r1: Rexp, r2: Rexp) extends Rexp
case class SEQ(r1: Rexp, r2: Rexp) extends Rexp
case class STAR(r: Rexp) extends Rexp

then the REPL complains that the value for SEQ and ALT is not found in
the
abstract class. The compiler (scala) accepts such definitions. Is
there an elegant
way to make the REPL also accept such definitions? Of course I can
wrap
everything into an object and everything in a big chunk, but I hope
there is
a better solution.

Thanks for the help,
Christian

rkuhn | 1 Jan 2012 15:44
Favicon

Re: REPL question

Hi Christian,

do you use :paste mode?

scala> :paste
[then
write
multiple
lines
of
code]
<press ctrl-d>

scala>

If you are entering single lines, each line must compile “by itself” (i.e. can only reference stuff on previous lines).

Regards,

Roland

Am Sonntag, 1. Januar 2012 15:32:24 UTC+1 schrieb urbanc:

Hi,

I am often writing small scala programs using Emacs and the REPL.
However, whenever
I define something like

abstract class Rexp {
  def ~ (right : Rexp) = SEQ(this, right)
  def || (right : Rexp) = ALT(this, right)
  def ** = STAR(this)
}

case object NULL extends Rexp
case object EMPTY extends Rexp
case class CHAR(c: Char) extends Rexp
case class ALT(r1: Rexp, r2: Rexp) extends Rexp
case class SEQ(r1: Rexp, r2: Rexp) extends Rexp
case class STAR(r: Rexp) extends Rexp

then the REPL complains that the value for SEQ and ALT is not found in
the
abstract class. The compiler (scala) accepts such definitions. Is
there an elegant
way to make the REPL also accept such definitions? Of course I can
wrap
everything into an object and everything in a big chunk, but I hope
there is
a better solution.

Thanks for the help,
Christian

Gmane