Scala 2.10 Arithmetic operations on case class variables

122 views
Skip to first unread message

l.a.derks

unread,
Feb 28, 2013, 8:50:41 AM2/28/13
to scala...@googlegroups.com
Hello

I have a case class which contains a couple of Long variables.

What is the best way to calculate the total sum of these variables?

regards,
Leon

√iktor Ҡlang

unread,
Feb 28, 2013, 9:09:53 AM2/28/13
to l.a.derks, scala-user
Using "+"?

You could do something like:
case class Foo(l: Long, i: Long)
val f = Foo(5, 6)
(0l /: f.productIterator) { case (sum: Long, v: Long) => sum + v }

but it's very brittle, as soon as you introduce a new field which happens to be a long, or make a long into an int, then you've silently broken your code.

Cheers,



--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Viktor Klang
Director of Engineering

Typesafe - The software stack for applications that scale
Twitter: @viktorklang

Rex Kerr

unread,
Feb 28, 2013, 9:10:21 AM2/28/13
to l.a.derks, scala...@googlegroups.com
The best way is to write a method that sums them explicitly.

Case classes extend Product so it is possible to

  p.productIterator.collect{ case l: Long => l }.foldLeft(0L)(_ + _)

where p is your case class, but you're in grave danger of adding some _other_ Long that happens to be there (and this is also way slower).

Just add a method that does the job.

If you have lots of case classes with the same variables, make a trait:

  trait SummableTwo {
    def a0: Long
    def a1: Long
    def sum = a0 + a1
  }

and have the appropriate case classes inherit from that

  case class FileSizes(f0: File, a0: Long, f1: File, a1: Long) extends SummableTwo {}

(you may wish to choose better variable names).

  --Rex
 

Léonard Schneider

unread,
Feb 28, 2013, 9:47:33 AM2/28/13
to scala...@googlegroups.com
LOL, if I had only a couple of Longs named a0 and a1, and c is an instance of my case class, then I would write c.a0 + c.a1
Maybe I misunderstood the use case then ;)

BR,


Leo

Erik Osheim

unread,
Feb 28, 2013, 12:17:21 PM2/28/13
to l.a.derks, scala...@googlegroups.com
On Thu, Feb 28, 2013 at 05:50:41AM -0800, l.a.derks wrote:
> What is the best way to calculate the total sum of these variables?

Spire [1] supports math operations on tuples (products), so you could
say something like:

import spire.implicits._
val pairs = List((9, 4), (1, 3), (44, 5), (-3, 12))
val sums = pairs.qsum // (51, 24)

We don't actually have direct support for case classes yet, although
the hope is that soon you'll be able to do something like this on case
classes directly, either via integration with shapeless, via macros, or
some other way.

-- Erik

[1] https://github.com/non/spire

kraythe

unread,
Feb 28, 2013, 3:43:41 PM2/28/13
to scala...@googlegroups.com
I wonder if there isnt something we arent understanding in your question. It seems a bit obvious. So let me try to guess.

Case classes are not any different than normal classes except that they MUST be immutable and they can be used in pattern matching. So writing:

class Foo(val x: Long)

is principally no different than writing:

case class Foo(val x: long)

So summing two items inside the class is a trivial matter. Now if you have a list of these case class instances and want to sum them all, that is a different question. So why dont you instead show us more, what you have tried and we can try to help :) 

-- Robert

Rich Oliver

unread,
Feb 28, 2013, 4:21:17 PM2/28/13
to scala...@googlegroups.com


On Thursday, February 28, 2013 8:43:41 PM UTC, kraythe wrote:
I wonder if there isnt something we arent understanding in your question. It seems a bit obvious. So let me try to guess.

Case classes are not any different than normal classes except that they MUST be immutable and they can be used in pattern matching. So writing:

class Foo(val x: Long)

is principally no different than writing:

case class Foo(val x: long)

So summing two items inside the class is a trivial matter. Now if you have a list of these case class instances and want to sum them all, that is a different question. So why dont you instead show us more, what you have tried and we can try to help :) 

-- Robert

You can miss out the val in a case class and it willl be inferred:

 case class Foo(x: :Long)

However case classes don't have to be immutable as in:

case class VarCase (var x: Int, var y: Int)
Reply all
Reply to author
Forward
0 new messages