'Ambiguous reference to overloaded definition' when override method in derived class - scala

I've got the following code:
import com.github.nscala_time.time.Imports._
class Account {
def balance(date: DateTime): Double = {
/* some logic that calculates balance on given date */
val calculatedBalance = 42
calculatedBalance
}
def balance: Double = balance(DateTime.now)
}
class Deposit(val interestRate: Double) extends Account {
override def balance(date: DateTime): Double = {
/* some logic that calculates balance for deposit account */
val calculatedBalance = 100 * interestRate;
calculatedBalance
}
}
I try to use these classes in the following way:
val simpleAccount = new Account
val depositAccount = new Deposit(0.1)
val simpleBalanceOnDate = simpleAccount.balance(DateTime.now + 1.month) // A
val depositBalanceOnDate = depositAccount.balance(DateTime.now + 1.month) // B
val simpleBalance = simpleAccount.balance // C
val depositBalance = depositAccount.balance // D
Cases A, B and C are compiled without any errors, but for the line D I see error message:
Error:(28, 38) ambiguous reference to overloaded definition,
both method balance in class Deposit of type (date: com.github.nscala_time.time.Imports.DateTime)Double
and method balance in class Account of type => Double
match expected type ?
val depositBalance = depositAccount.balance
^
Can you please explain why there is a compilation error in case D and why there are no in case C?
Thanks in advance!

I suppose the compiler is confused about parameterless method inheritance, although I can't explain why honestly, for a quick solution this should work:
class Account {
{ ... }
def balance(): Double = balance(DateTime.now)
}
val depositAccount = new Deposit(0.1)
val depositBalance = depositAccount.balance()
Why this happens is obscure to me, maybe somebody else knows how the scala compiler is seeing parameterless method inheritance.
Also reading around, specifically Programming in Scala:
Such parameterless methods are quite common in Scala. By contrast, methods defined with empty parentheses, such as def height(): Int, are called empty-paren methods. The recommended convention is to use a parameterless method whenever there are no parameters and the method accesses mutable state only by reading fields of the containing object (in particular, it does not change mutable state).
This convention supports the uniform access principle,1 which says that client code should not be affected by a decision to implement an attribute as a field or method. For instance, we could have chosen to implement width and height as fields instead of methods, simply by changing the def in each definition to a val:
abstract class Element {
def contents: Array[String]
val height = contents.length
val width =
if (height == 0) 0 else contents(0).length
}
The two pairs of definitions are completely equivalent from a client's point of view. The only difference is that field accesses might be slightly faster than method invocations, because the field values are pre-computed when the class is initialized, instead of being computed on each method call. On the other hand, the fields require extra memory space in each Element object. So it depends on the usage profile of a class whether an attribute is better represented as a field or method, and that usage profile might change over time. The point is that clients of the Element class should not be affected when its internal implementation changes.

Why don't you provide a default argument like this:
class Account {
def balance(date: DateTime = DateTime.now): Double = {
/* some logic that calculates balance on given date */
val calculatedBalance = 42
calculatedBalance
}
}
class Deposit(val interestRate: Double) extends Account {
override def balance(date: DateTime): Double = {
/* some logic that calculates balance for deposit account */
val calculatedBalance = 100 * interestRate;
calculatedBalance
}
}
val simpleBalanceOnDate = simpleAccount.balance(1) // A
val depositBalanceOnDate = depositAccount.balance(1) // B
val simpleBalance = simpleAccount.balance() // C
val depositBalance = depositAccount.balance() // D

Related

How can I view the code that Scala uses to automatically generate the apply function for case classes?

When defining a Scala case class, an apply function is automatically generated which behaves similarly to the way the default constructor in java behaves. How can I see the code which automatically generates the apply function? I presume the code is a macro in the Scala compiler somewhere but I'm not sure.
To clarify I am not interested in viewing the resultant apply method of a given case class but interested in the macro/code which generates the apply method.
It's not a macro. Methods are synthesized by compiler "manually".
apply, unapply, copy are generated in scala.tools.nsc.typechecker.Namers
https://github.com/scala/scala/blob/2.13.x/src/compiler/scala/tools/nsc/typechecker/Namers.scala#L1839-L1862
/** Given a case class
* case class C[Ts] (ps: Us)
* Add the following methods to toScope:
* 1. if case class is not abstract, add
* <synthetic> <case> def apply[Ts](ps: Us): C[Ts] = new C[Ts](ps)
* 2. add a method
* <synthetic> <case> def unapply[Ts](x: C[Ts]) = <ret-val>
* where <ret-val> is the caseClassUnapplyReturnValue of class C (see UnApplies.scala)
*
* #param cdef is the class definition of the case class
* #param namer is the namer of the module class (the comp. obj)
*/
def addApplyUnapply(cdef: ClassDef, namer: Namer): Unit = {
if (!cdef.symbol.hasAbstractFlag)
namer.enterSyntheticSym(caseModuleApplyMeth(cdef))
val primaryConstructorArity = treeInfo.firstConstructorArgs(cdef.impl.body).size
if (primaryConstructorArity <= MaxTupleArity)
namer.enterSyntheticSym(caseModuleUnapplyMeth(cdef))
}
def addCopyMethod(cdef: ClassDef, namer: Namer): Unit = {
caseClassCopyMeth(cdef) foreach namer.enterSyntheticSym
}
https://github.com/scala/scala/blob/2.13.x/src/compiler/scala/tools/nsc/typechecker/Namers.scala#L1195-L1219
private def templateSig(templ: Template): Type = {
//...
// add apply and unapply methods to companion objects of case classes,
// unless they exist already; here, "clazz" is the module class
if (clazz.isModuleClass) {
clazz.attachments.get[ClassForCaseCompanionAttachment] foreach { cma =>
val cdef = cma.caseClass
assert(cdef.mods.isCase, "expected case class: "+ cdef)
addApplyUnapply(cdef, templateNamer)
}
}
// add the copy method to case classes; this needs to be done here, not in SyntheticMethods, because
// the namer phase must traverse this copy method to create default getters for its parameters.
// here, clazz is the ClassSymbol of the case class (not the module). (!clazz.hasModuleFlag) excludes
// the moduleClass symbol of the companion object when the companion is a "case object".
if (clazz.isCaseClass && !clazz.hasModuleFlag) {
val modClass = companionSymbolOf(clazz, context).moduleClass
modClass.attachments.get[ClassForCaseCompanionAttachment] foreach { cma =>
val cdef = cma.caseClass
def hasCopy = (decls containsName nme.copy) || parents.exists(_.member(nme.copy).exists)
// scala/bug#5956 needs (cdef.symbol == clazz): there can be multiple class symbols with the same name
if (cdef.symbol == clazz && !hasCopy)
addCopyMethod(cdef, templateNamer)
}
}
equals, hashCode, toString are generated in scala.tools.nsc.typechecker.SyntheticMethods
https://github.com/scala/scala/blob/2.13.x/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
/** Synthetic method implementations for case classes and case objects.
*
* Added to all case classes/objects:
* def productArity: Int
* def productElement(n: Int): Any
* def productPrefix: String
* def productIterator: Iterator[Any]
*
* Selectively added to case classes/objects, unless a non-default
* implementation already exists:
* def equals(other: Any): Boolean
* def hashCode(): Int
* def canEqual(other: Any): Boolean
* def toString(): String
*
* Special handling:
* protected def writeReplace(): AnyRef
*/
trait SyntheticMethods extends ast.TreeDSL {
//...
Symbols for accessors are created in scala.reflect.internal.Symbols
https://github.com/scala/scala/blob/2.13.x/src/reflect/scala/reflect/internal/Symbols.scala#L2103-L2128
/** For a case class, the symbols of the accessor methods, one for each
* argument in the first parameter list of the primary constructor.
* The empty list for all other classes.
*
* This list will be sorted to correspond to the declaration order
* in the constructor parameter
*/
final def caseFieldAccessors: List[Symbol] = {
// We can't rely on the ordering of the case field accessors within decls --
// handling of non-public parameters seems to change the order (see scala/bug#7035.)
//
// Luckily, the constrParamAccessors are still sorted properly, so sort the field-accessors using them
// (need to undo name-mangling, including the sneaky trailing whitespace)
//
// The slightly more principled approach of using the paramss of the
// primary constructor leads to cycles in, for example, pos/t5084.scala.
val primaryNames = constrParamAccessors map (_.name.dropLocal)
def nameStartsWithOrigDollar(name: Name, prefix: Name) =
name.startsWith(prefix) && name.length > prefix.length + 1 && name.charAt(prefix.length) == '$'
caseFieldAccessorsUnsorted.sortBy { acc =>
primaryNames indexWhere { orig =>
(acc.name == orig) || nameStartsWithOrigDollar(acc.name, orig)
}
}
}
private final def caseFieldAccessorsUnsorted: List[Symbol] = info.decls.toList.filter(_.isCaseAccessorMethod)
Perhaps I could point out few points in the codebase that might be relevant.
First, there is a way to correlate Scala Language Specification grammar directly to source code. For example, case classes rule
TmplDef ::= β€˜case’ β€˜class’ ClassDef
relates to Parser.tmplDef
/** {{{
* TmplDef ::= [case] class ClassDef
* | [case] object ObjectDef
* | [override] trait TraitDef
* }}}
*/
def tmplDef(pos: Offset, mods: Modifiers): Tree = {
...
in.token match {
...
case CASECLASS =>
classDef(pos, (mods | Flags.CASE) withPosition (Flags.CASE, tokenRange(in.prev /*scanner skips on 'case' to 'class', thus take prev*/)))
...
}
}
Specification continues
A case class definition of 𝑐[tps](ps1)…(ps𝑛) with type parameters
tps and value parameters ps implies the definition of a companion
object, which serves as an extractor object.
object 𝑐 {
def apply[tps](ps1)…(ps𝑛): 𝑐[tps] = new 𝑐[Ts](xs1)…(xs𝑛)
def unapply[tps](π‘₯: 𝑐[tps]) =
if (x eq null) scala.None
else scala.Some(π‘₯.xs11,…,π‘₯.xs1π‘˜)
}
so let us try to hunt for implied definition of
def apply[tps](ps1)…(ps𝑛): 𝑐[tps] = new 𝑐[Ts](xs1)…(xs𝑛)
which is another way of saying synthesised definition. Promisingly, there exists MethodSynthesis.scala
/** Logic related to method synthesis which involves cooperation between
* Namer and Typer.
*/
trait MethodSynthesis {
Thus we find two more potential clues Namer and Typer. I wonder what is in there? But first MethodSynthesis.scala has only approx 300 LOC, so let us just skim through a bit. We stumble accross a promising line
val methDef = factoryMeth(classDef.mods & (AccessFlags | FINAL) | METHOD | IMPLICIT | SYNTHETIC, classDef.name.toTermName, classDef)
"factoryMeth"... there is a ring to it. Find usages! We are quickly led to
/** The apply method corresponding to a case class
*/
def caseModuleApplyMeth(cdef: ClassDef): DefDef = {
val inheritedMods = constrMods(cdef)
val mods =
if (applyShouldInheritAccess(inheritedMods))
(caseMods | (inheritedMods.flags & PRIVATE)).copy(privateWithin = inheritedMods.privateWithin)
else
caseMods
factoryMeth(mods, nme.apply, cdef)
}
It seems we are on the right track. We also note the name
nme.apply
which is
val apply: NameType = nameType("apply")
Eagerly, we find usages of caseModuleApplyMeth and we are wormholed to Namer.addApplyUnapply
/** Given a case class
* case class C[Ts] (ps: Us)
* Add the following methods to toScope:
* 1. if case class is not abstract, add
* <synthetic> <case> def apply[Ts](ps: Us): C[Ts] = new C[Ts](ps)
* 2. add a method
* <synthetic> <case> def unapply[Ts](x: C[Ts]) = <ret-val>
* where <ret-val> is the caseClassUnapplyReturnValue of class C (see UnApplies.scala)
*
* #param cdef is the class definition of the case class
* #param namer is the namer of the module class (the comp. obj)
*/
def addApplyUnapply(cdef: ClassDef, namer: Namer): Unit = {
if (!cdef.symbol.hasAbstractFlag)
namer.enterSyntheticSym(caseModuleApplyMeth(cdef))
val primaryConstructorArity = treeInfo.firstConstructorArgs(cdef.impl.body).size
if (primaryConstructorArity <= MaxTupleArity)
namer.enterSyntheticSym(caseModuleUnapplyMeth(cdef))
}
Woohoo! The documentation states
<synthetic> <case> def apply[Ts](ps: Us): C[Ts] = new C[Ts](ps)
which seems eerily similar to SLS version
def apply[tps](ps1)…(ps𝑛): 𝑐[tps] = new 𝑐[Ts](xs1)…(xs𝑛)
Our stumbling-in-the-dark seems to have led us to a discovery.
I noticed that, while others have posted the pieces of code that generate the name of the method, the signature, the type, the corresponding symbols in the symbol table, and pretty much everything else, so far nobody has posted the piece of code that generates the actual body of the case class companion object apply method.
That code is in scala.tools.nsc.typechecker.Unapplies.factoryMeth(mods: Global.Modifiers, name: Global.TermName, cdef: Global.ClassDef): Global.DefDef which is defined in src/compiler/scala/tools/nsc/typechecker/Unapplies.scala, and the relevant part is this:
atPos(cdef.pos.focus)(
DefDef(mods, name, tparams, cparamss, classtpe,
New(classtpe, mmap(cparamss)(gen.paramToArg)))
)
which uses the TreeDSL internal Domain Specific Language for generating Syntax Nodes in the Abstract Syntax Tree, and (roughly) means this:
At the current position in the tree (atPos(cdef.pos.focus))
Splice in a method definition node (DefDef)
Whose body is just a New node, i.e. a constructor invocation.
The description of the TreeDSL trait states:
The goal is that the code generating code should look a lot like the code it generates.
And I think that is true, and makes the code easy to read even if you are not familiar with the compiler internals.
Compare the generating code once again with the generated code:
DefDef(mods, name, tparams, cparamss, classtpe,
New(classtpe, mmap(cparamss)(gen.paramToArg)))
def apply[Tparams](constructorParams): CaseClassType =
new CaseClassType(constructorParams)

Set an implicit function return in Scala

I am writing DSL (domain specific language for my code).
The code is:
class NeuronGroupDSL(identifier: String)(implicit network: N2S3SimulationDSL ) // declared values which must be provided by the user, [we can just give a default constructor to this]
{
implicit val sizeDefault : Int = 28 // added the implicit default value for the setNumberOfNeurons method
val id: String = identifier // We can add a default constructor with the Id and the network to this too allow user to skip this part
var neuronGroup: Option[NeuronGroupRef] = None // this variable stores all the information by using the get property and a associated function with it
private var neuronParameters: Seq[(Property[_], _)] = Seq()
private var neuronModel: NeuronModel = _
/**Properties of the NeuronGroupDSL **/
// Added a default size to the size variable
def ofSize(implicit size: Int): NeuronGroupDSL = {
this.neuronGroup.get.setNumberOfNeurons(size)
this
}
// Give user the opportunity to choose the type of available models by the help of pattern matching
/**Neuron Model:
1. Linear leaky integrate-and-fire model
2. FitzHugh-Nagumo model
3. Izhikevich model
**/
def modeling(model: NeuronModel): NeuronGroupDSL = {
this.neuronModel = model
this.neuronGroup.get.setNeuronModel(model, this.neuronParameters)
this
}
//we can define a default property the neuron group model here
def withParameters(properties: (Property[_], _)*): NeuronGroupDSL = {
this.neuronParameters = properties
this.neuronGroup.get.setNeuronModel(this.neuronModel, properties)
this
}
}
As you can see the definitions ofSize modeling withParameters have the same return type, so is it possible to implicitly define their return type and define these functions without their return part ?
Please help me I want to minimize the code as much as possible.
I too want to know that is it possible to use case class , concise lambda syntax in this code to further minimize it.
You can simply drop the return type, it will be inferred automatically:
def ofSize(implicit size: Int) = {
neuronGroup.get.setNumberOfNeurons(size)
this
}

Enum.Value vs Enum#Value

I'm learning Scala coming from a Java background, and the first thing I've found that works significantly differently than Java are the Enums. I've managed to accomplish everything I've wanted to just by trial and error, but I'd love to better understand what I'm doing along the way.
From the Scala documentation, I'm told to create an enum by extending the class Enumeration, and add values by setting them equal to a constant Value, eg:
object Label extends Enumeration{
val NONE = Value
}
This works about as expected. My trouble comes in using not only enums but extensions of custom written enum extensions. I wrote a chunk of code as part of a Machine Learning class (now over) to separate data by their labels (for use in TDIDT, for example). At the bottom is a small piece of it to get at where I'm confused. The Data object is runnable, just to try it out.
First, on the print statement, I thought it would be true, but it is not
println(Label.NONE.equals(MessageLabel.NONE))//Thought this would be true, is false
Why is this the case? Is that even though the NONE that MessageLabel has inherited is directly from Label, the type system insists that they are different enum values?
Secondly and more importantly I've been going back and forth between Label.Value and Label#Value basically willy-nilly. The version that I posted with:
def splitByLabel[T <: Label#Value]
trait Labelable[T <: Label#Value]
abstract class Data[T <: Label#Value]
class Message( ... val label : MessageLabel.Value)
Compiles and runs correctly. When I change all the #s to ., I get a compile time error on the line splitByLabel(messages).foreach(a => println(a)), stating:
Inferred type arguments [MessageLabel.Value] do not conform to method splitByLabel's type parameter bounds[T <: Label.Value]
But when I change all the .s to #s, I get a compile time error on the line class Message(val index : Int, val s : Map[Double, Int], override val label : MessageLabel#Value) extends Data[MessageLabel#Value](label), stating:
Not Found: Type MessageLabel
So clearly there is a difference between the two and they each fill a specific role. Can someone help me understand what the difference is? Thank you!
/** Enum type all labels should extend. Guarantees access of universal NONE label */
class Label extends Enumeration{
val NONE = Value
}
/** Singleton instance for accessing NONE */
object Label extends Label{}
/** Companion object to all data classes. Hosts helper methods and a runnable main method */
object Data{
/** Returns a map of lists, each list is similarly labeled data. Map is label -> list of data */
def splitByLabel[T <: Label#Value](elms : List[Labelable[T]]) : Map[T, List[Labelable[T]]] = {
def f(acc : Map[T, List[Labelable[T]]], e : Labelable[T]) : Map[T, List[Labelable[T]]] = {
if(acc.contains(e.label)){
val l = acc(e.label)
acc - e.label + ((e.label, (e :: l)))
} else{
acc + ((e.label, List(e)))
}
}
elms.foldLeft(Map[T, List[Labelable[T]]]())(f)
}
def main(args : Array[String]){
println(Label.NONE.equals(MessageLabel.NONE))
val messages : List[Message] = (0 to 10).toList.map(a =>
new Message(a, Map(), if(a % 3 == 0) MessageLabel.HAM else MessageLabel.SPAM))
splitByLabel(messages).foreach(a => println(a))
}
}
/** Implementing classes can be labeled */
trait Labelable[T <: Label#Value]{
/** Returns the label of this thing */
val label : T
/** The possible labelings for this thing */
val labels : List[T]
}
abstract class Data[T <: Label#Value](override val label : T) extends Labelable[T]{
override def toString(): String = {
if (label != null)
label.toString
else
"NO_LABEL"
}
}
object MessageLabel extends Label{
val HAM, SPAM = Value
}
/** An instance represents a sentence. */
class Message(val index : Int, val s : Map[Int, Double], override val label : MessageLabel.Value)
extends Data[MessageLabel.Value](label){
/** Returns the possible labelings for a message */
override val labels = MessageLabel.values.toList
/** Adds index to tostring at front */
override def toString() : String = {
index + "-" + super.toString
}
}
Label#Value is the type Value in the type Label. Label.Value is the type Value in the value Label. (It's a bit confusing because you have both class Label and object Label (i.e. a value)). So a MessageLabel.Value is a Label#Value, because MessageLabel is an instance of the type (class) Label. But it isn't a Label.Value, because MessageLabel isn't the value (object) Label. And there is no MessageLabel#Value because there is no class MessageLabel (or trait).
(FWIW I find scala Enumeration very confusing and prefer to use Java enums in my Scala code)
This is not particular to Enumeration.
scala> class A { class B ; val None = new B }
defined class A
scala> class C extends A ; class D extends A
defined class C
defined class D
scala> val c = new C ; val d = new D
c: C = C#45fe3ee3
d: D = D#4cdf35a9
scala> c.None == d.None
res0: Boolean = false
No one would ever expect that to be true. One value is initialized in one (super-) constructor, another in the other.
Also, Value is not a constant; it's a function that says, "Give me another Value." So you're generating a value for each instance.
In Java, you can't extend enums in this sense. To "extend" is to add members or increase the extension, but subclassing means a subset or restricted domain.
This is a case where one prefers composition over inheritance. Given a set of weekdays and of weekend days, I get alldays by adding them, not by extending weekdays with the weekend.
Here is an example of using an Enumeration in a path-dependent way.
Another issue with the code as it stands:
scala> MessageLabel.NONE
res4: MessageLabel.Value = <Invalid enum: no field for #0>
https://issues.scala-lang.org/browse/SI-5147

How to create a Scala class with private field with public getter, and primary constructor taking a parameter of the same name

Search results so far have led me to believe this is impossible without either a non-primary constructor
class Foo { // NOT OK: 2 extra lines--doesn't leverage Scala's conciseness
private var _x = 0
def this(x: Int) { this(); _x = x }
def x = _x
}
val f = new Foo(x = 123) // OK: named parameter is 'x'
or sacrificing the name of the parameter in the primary constructor (making calls using named parameters ugly)
class Foo(private var _x: Int) { // OK: concise
def x = _x
}
val f = new Foo(_x = 123) // NOT OK: named parameter should be 'x' not '_x'
ideally, one could do something like this:
class Foo(private var x: Int) { // OK: concise
// make just the getter public
public x
}
val f = new Foo(x = 123) // OK: named parameter is 'x'
I know named parameters are a new thing in the Java world, so it's probably not that important to most, but coming from a language where named parameters are more popular (Python), this issue immediately pops up.
So my question is: is this possible? (probably not), and if not, why is such an (in my opinion) important use case left uncovered by the language design? By that, I mean that the code either has to sacrifice clean naming or concise definitions, which is a hallmark of Scala.
P.S. Consider the case where a public field needs suddenly to be made private, while keeping the getter public, in which case the developer has to change 1 line and add 3 lines to achieve the effect while keeping the interface identical:
class Foo(var x: Int) {} // no boilerplate
->
class Foo { // lots of boilerplate
private var _x: Int = 0
def this(x: Int) { this(); _x = x }
def x = _x
}
Whether this is indeed a design flaw is rather debatable. One would consider that complicating the syntax to allow this particular use case is not worthwhile.
Also, Scala is after all a predominantly functional language, so the presence of vars in your program should not be that frequent, again raising the question if this particular use case needs to be handled in a special way.
However, it seems that a simple solution to your problem would be to use an apply method in the companion object:
class Foo private(private var _x: Int) {
def x = _x
}
object Foo {
def apply(x: Int): Foo = new Foo(x)
}
Usage:
val f = Foo(x = 3)
println(f.x)
LATER EDIT:
Here is a solution similar to what you originally requested, but that changes the naming a bit:
class Foo(initialX: Int) {
private var _x = initialX
def x = _x
}
Usage:
val f = new Foo(initialX = 3)
The concept you are trying to express, which is an object whose state is mutable from within the object and yet immutable from the perspective of other objects ... that would probably be expressed as an Akka actor within the context of an actor system. Outside the context of an actor system, it would seem to be a Java conception of what it means to be an object, transplanted to Scala.
import akka.actor.Actor
class Foo(var x: Int) extends Actor {
import Foo._
def receive = {
case WhatIsX => sender ! x
}
}
object Foo {
object WhatIsX
}
Not sure about earlier versions, but In Scala 3 it can easily be implemented like follows:
// class with no argument constructor
class Foo {
// prive field
private var _x: Int = 0
// public getter
def x: Int = _x
// public setter
def x_=(newValue: Int): Unit =
_x = newValue
//auxiliary constructor
def this(value: Int) =
this()
_x = value
}
Note
Any definition within the primary constructor makes the definition public, unless you prepend it with private modifier
Append _= after a method name with Unit return type to make it a setter
Prepending a constructor parameter neither with val nor with var, makes it private
Then it follows:
val noArgFoo = Foo() // no argument case
println(noArgFoo.x) // the public getter prints 0
val withArgFoo = Foo(5) // with argument case
println(withArgFoo.x) // the public getter prints 5
noArgFoo.x = 100 // use the public setter to update x value
println(noArgFoo.x) // the public getter prints 100
withArgFoo.x = 1000 // use the public setter to update x value
println(withArgFoo.x) // the public getter prints 1000
This solution is exactly what you asked; in a principled way and without any ad hoc workaround e.g. using companion objects and the apply method.

Scala Numeric init with constant 0

Lets I have a utility class called MathUtil.
and it looks like this .
abstract class MathUtil(T:Numeric){
def nextNumber(value:T)
def result():T
}
Lets I subclass it this way
class SumUtil[T:Numeric] extends MathUtil[T]{
private var sum:T = 0
override def nextNumber(value:T){
sum = sum + value
}
override def result():T = sum
}
I have a problem with the statement
private var sum:T = 0
Now , I have to initialize to sum to 0. I would guess any numeric to have a way to represent 0. Im pretty new to scala. How do I solve this issue ?
The Numeric type class instance has a zero method that does what you want:
class SumUtil[T: Numeric] extends MathUtil[T] {
private var sum: T = implicitly[Numeric[T]].zero
override def nextNumber(value: T) {
sum = implicitly[Numeric[T]].plus(sum, value)
}
override def result(): T = sum
}
Note that you also need the instance for the plus method, unless you import Numeric.Implicits._, in which case you can use +. You can also clean the code up a bit by not using the context bound syntax in this case:
class SumUtil[T](implicit ev: Numeric[T]) extends MathUtil[T] {
import Numeric.Implicits._
private var sum: T = ev.zero
override def nextNumber(value: T) {
sum = sum + value
}
override def result(): T = sum
}
This is exactly equivalent: the context bound version is just syntactic sugar for this implicit argument, but if you need to use that argument explicitly (as you do here, for its zero), I find it cleaner to write the desugared version.
I think that there needs to be a little clarification of exactly what you're trying to accomplish. From the Scala docs, the Numeric type itself is generic. My feeling here is what you actually want is to describe a MathUtil abstraction that handles any Numeric[T] rather than subclasses of Numeric[_] which is what your code is currently describing. Here is the correct implementation based on that assumption.
//Define a MathUtil that works on any T
abstract class MathUtil[T] {
def nextNumber(value: T)
def result(): T
}
//Define a SumUtil that works on any T that has an available Numeric
//Will search implicit scope, but also allows you to provide an
//implementation if desired.
class SumUtil[T](implicit n: Numeric[T]) extends MathUtil[T] {
//Use the Numeric to generate the zero correctly.
private var sum: T = n.zero
//Use the Numeric to correctly add the sum and value
override def nextNumber(value: T) = sum = n.plus(sum, value)
override def result(): T = sum
}
//Test that it works.
val a = new SumUtil[Int]
val b = List(1,2,3)
b map a.nextNumber //Quick and dirty test... returns a meaningless list
println(a.result) //Does indeed print 6
If the above doesn't do what you want, please clarify your question.