Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get around the Scala case class limit of 22 fields?

Scala case classes have a limit of 22 fields in the constructor. I want to exceed this limit, is there a way to do it with inheritance or composition that works with case classes?

like image 947
Phil Avatar asked Nov 28 '13 05:11

Phil


People also ask

What is the benefit of case class in Scala?

The one of the topmost benefit of Case Class is that Scala Compiler affix a method with the name of the class having identical number of parameters as defined in the class definition, because of that you can create objects of the Case Class even in the absence of the keyword new.

Can Scala case class have methods?

case classes automatically have equality and nice toString methods based on the constructor arguments. case classes can have methods just like normal classes.


1 Answers

More recently (Oct 2016, six years after the OP), the blog post "Scala and 22" from Richard Dallaway explores that limit:

Back in 2014, when Scala 2.11 was released, an important limitation was removed:

Case classes with > 22 parameters are now allowed.  

That said, there still exists a limit on the number of case class fields, please see https://stackoverflow.com/a/55498135/1586965

This may lead you to think there are no 22 limits in Scala, but that’s not the case. The limit lives on in functions and tuples.

The fix (PR 2305) introduced in Scala 2.11 removed the limitation for the above common scenarios: constructing case classes, field access (including copying), and pattern matching (baring edge cases).

It did this by omitting unapply and tupled for case classes above 22 fields.
In other words, the limit to Function22 and Tuple22 still exists.

Working around the Limit (post Scala 2.11)

There are two common tricks for getting around this limit.

  • The first is to use nested tuples.
    Although it’s true a tuple can’t contain more than 22 elements, each element itself could be a tuple

  • The other common trick is to use heterogeneous lists (HLists), where there’s no 22 limit.

If you want to make use of case classes, you may be better off using the shapeless HList implementation. We’ve created the Slickless library to make that easier. In particular the recent mappedWith method converts between shapeless HLists and case classes. It looks like this:

import slick.driver.H2Driver.api._ import shapeless._ import slickless._  class LargeTable(tag: Tag) extends Table[Large](tag, "large") {   def a = column[Int]("a")   def b = column[Int]("b")   def c = column[Int]("c")   /* etc */   def u = column[Int]("u")   def v = column[Int]("v")   def w = column[Int]("w")    def * = (a :: b :: c :: /* etc */ :: u :: v :: w :: HNil)     .mappedWith(Generic[Large]) } 

There’s a full example with 26 columns in the Slickless code base.

like image 179
VonC Avatar answered Oct 06 '22 23:10

VonC