Using .tupled method when companion object is in class
Solution 1
You can also write
(Person.apply _).tupled
to avoid repeating the types.
Solution 2
This is very similar to what Alexey Romanov said, but in order to avoid lifting apply
whenever you need tupled
, we just add it to our companion objects.
object Person {
def something = "rawr"
def tupled = (Person.apply _).tupled
}
Now you can call Person.tupled
just like you would have if it didn't have a companion object.
Solution 3
One workaround is define a companion object as follows:
object Person extends((String,String) => Person) {
...
}
See. https://groups.google.com/d/msg/scala-user/jyWBMz5Qslw/Bryv4ftzRLgJ
Solution 4
To build on some of the other comments you could do the following as well since tuple is calling the generated default apply method for the case class.
object Person {
...
def tupled = (this.apply _).tupled
}
Related videos on Youtube
mdedetrich
Updated on January 10, 2021Comments
-
mdedetrich over 3 years
I am in the process of migrating from Slick to Slick 2, and in Slick 2 you are meant to use the
tupled
method when projecting onto a case class (as shown here http://slick.typesafe.com/doc/2.0.0-RC1/migration.html)The problem is when the case class has a companion object, i.e. if you have something like this
case class Person(firstName:String, lastName:String) { }
Along with a companion object
object Person { def something = "rawr" }
In the same scope, the
tupled
method no longer works, because its trying to runtupled
on theobject
, instead of thecase class
.Is there a way to retrieve the
case class
ofPerson
rather than theobject
, so you can calltupled
properly?-
Erik Kaplun about 10 yearsdo you absolutely need the companion object? also, I think this is a general Scala question not really Slick related.
-
mdedetrich about 10 yearsYes I do, unless I want to refactor like half of my project (the companion object has a lot of helper methods for the case class in question) And yes you are right, its not directly related to slick, just mentioned it because Slick may have its own workaround
-
Erik Kaplun about 10 yearsYou can't just rename the companion object and import the renamed object's contents directly to the case class? Alternatively, you can just make your custom companion object look like an autogenerated one manually.
-
mdedetrich about 10 yearsIs what I am asking something impossible to do? I mean I can do that (amongst various other options), but that object is used in hundreds of places, so it would be a pretty painful refactor
-
Erik Kaplun about 10 yearsI've proposed a workaround, so no, it's not impossible, but it's ugly... overriding case class companion objects isn't really intended, otherwise what's the point of using the case class in the first place? case classes are afaik just syntactic sugar over regular classes + autogenerated companions with
apply
andunapply
... if you override the autogen. companion, you're by definition defeating the purpose of case classes. -
mdedetrich about 10 yearsWell it was a design choice, you override the case class with an object for the same reason you use static final in java, that is, you want to attach helper methods onto a namespace In this case I want to attach helper methods to the
Person
namespace, things like apply and unapply are just for creating an instance of Person (which case classes generate), however it doesn't have anything to do with the other methods that are attached to thePerson
type -
Erik Kaplun about 10 yearsAs I said, you can put the helper functions in any object and import them to
Person
; it doesn't have to be a companion object. -
mdedetrich about 10 yearsYes, but idiomatically speaking, if you have global functions that deal with
Person
, they should work on thePerson
namespace, thats the whole purpose of the Singleton Pattern There is a reason when have global methods withBigDecimal
(as an example), the methods are attached toBigDecimal
, and notBigDecimalHelpers
or something like that -
Erik Kaplun about 10 yearsIt's hardly idiomatic to override and then re-implement the gist of case classes.
-
mdedetrich about 10 yearsThe intention to use an object with the same namespace as its
case class
is not to override thecase class
, the intention is to add methods/values from theobject
into the same namespace of thecase class
. This practice is done in almost every mainstream OOP language (including Java,Scala and others). You are not overriding or reimplementing thecase classes
(unless you are definingapply
,unapply
in yourobject
), you are adding ontop of the namespace. Whether aclass
is acase class
or a normalclass
is irrelevant,case classes
just add an apply/unapply methods. -
Erik Kaplun about 10 yearsOK, I see, but when why did the
tupled
method disappear? -
mdedetrich about 10 yearsActually they don't disappear, have a look at this answer stackoverflow.com/a/22368413/1519631. As to why the
tupled
method "disappears", I have no clue. After some quick reading, it may be down to how its brought into scopes by implicits (this is done internally). Remember that you can still usecase classes
fine, even if there is a companionobject
. This issue only cropped up because I specifically needed to use the tupled method
-
-
mdedetrich about 10 yearsThanks, that actually works (I assume there isn't any workaround for the boilerplate that is (String,String) )
-
AHonarmand almost 6 yearsWhat if the companion object has its own apply method (an overloaded constructor)? Compiler cannot resolve the apply...
-
AHonarmand almost 6 yearsFound the answer: stackoverflow.com/questions/41179532/…
-
WestCoastProjects over 5 yearsthis is not compiling:
apply
not found -
Alexey Romanov over 5 years@javadba Yes, it is: scalafiddle.io/sf/a5rsgke/0. Are you sure you have a case class?