Suppose that I want to write a case class Stepper as follows:
case class Stepper(step: Int) {def apply(x: Int) = x + step}
It comes with a nice toStringimplementation:
scala> Stepper(42).toString
res0: String = Stepper(42)
but it’s not really a function:
scala> Some(2) map Stepper(2)
<console>:10: error: type mismatch;
found : Stepper
required: Int => ?
Some(2) map Stepper(2)
A workaround is to implement the Function trait…
case class Stepper(step: Int) extends (Int => Int) {def apply(x: Int) = x + step}
But then, I can’t have for free a nice toString implementation anymore:
scala> Stepper(42).toString
res2: java.lang.String = <function1>
Then, the question is: can I have the best of these two worlds? Is there a solution where I have the nice toString implementation for free AND an implementation of trait Function. In other words, is there a way to apply the linearization in such a way that case class syntaxic sugar is applied at last?
The question is not really to do with linearisation. In case-classes
toStringis a method automatically generated by the compiler if and only ifAny.toStringis not overridden in the end-type.However, the answer is partly to do with linearisation – we need to override
Function1.toStringwith the method that would have been generated by compiler if not for the version introduced byFunction1:Then
Will produce
Update
Here is a version of
ProperNametrait that doesn’t rely on the undocumented API method:Alternative
toStringimplementation is derived from the source code for the original_toStringmethodscala.runtime.ScalaRunTime._toString.Please note that this alternative implementation is still based on the assumption that a case class always extends
Producttrait. Although the latter holds true as of Scala 2.9.0 and is a fact that is known to and relied upon by some members of Scala community it’s not formally documented as part of Scala Language Spec.