Scala Numeric init with constant 0

I have a MathUtil utility class.

and it looks like this.

abstract class MathUtil(T:Numeric){ def nextNumber(value:T) def result():T } 

Allows you to subclass it in 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 approval

 private var sum:T = 0 

Now I need to initialize the summation to 0. I would suggest that any numeric value has a way of representing 0. Im pretty new to scala. How to solve this problem?

+6
source share
2 answers

Numeric class instance type 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 an instance for the plus method if you are not importing Numeric.Implicits._ , in which case you can use + . You can also clear the code a bit without using the context-related 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-related version is just syntactic sugar for this implicit argument, but if you need to explicitly use this argument (as you are here for its zero ), I find it cleaner to write desugared.

+11
source

I think we need to clarify a little what exactly you are trying to accomplish. Of the Scala docs, the Numeric type itself is generic. My feeling here is that what you really want is to describe an abstraction of MathUtil that handles any numeric [T], not the Numeric [_] subclasses that are currently being described by your code. Here is the correct implementation based on this 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 does not do what you want, clarify your question.

0
source

Source: https://habr.com/ru/post/918794/


All Articles