How to collapse the BigDecimal list? ("overloaded method + cannot be applied")

I want to write a short functional summing function for a BigDecimal list and tried with:

def sum(xs: List[BigDecimal]): BigDecimal = (0 /: xs) (_ + _) 

But I got this error message:

 <console>:7: error: overloaded method value + with alternatives: (x: Int)Int <and> (x: Char)Int <and> (x: Short)Int <and> (x: Byte)Int cannot be applied to (BigDecimal) def sum(xs: List[BigDecimal]): BigDecimal = (0 /: xs) (_ + _) ^ 

If I use Int instead, this function works. I think this is due to overloading the BigDecimal operator from + . What is a good workaround for BigDecimal?

+4
source share
4 answers

The problem is the actual value. The solution here is pretty simple:

  sum(xs: List[BigDecimal]): BigDecimal = (BigDecimal(0) /: xs) (_ + _) 
+16
source

foldLeft requires an initialization value.

 def foldLeft[B](z: B)(f: (B, A) ⇒ B): B 

This initialization value (named z ) must be of the same type as the bending type:

 (BigDecimal(0) /: xs) { (sum: BigDecimal, x: BigDecimal) => sum+x } // with syntax sugar (BigDecimal(0) /: xs) { _+_ } 

If you add an Int initialization value, foldLeft will look like this:

 (0 /: xs) { (sum: Int, x: BigDecimal) => sum+x } // error: not possible to add a BigDecimal to Int 
+2
source

In such a situation (where the battery has the same type as the elements in the list), you can start addition by adding the first and second elements to the list, i.e. you do not need an initial value, Scala reduce provides this kind of bend:

 def sum(xs: List[BigDecimal]) = xs.reduce(_ + _) 

There are also versions of reduceLeft and reduceRight if your operation is not associative.

+2
source

As others have already said, you received an error due to the initial value, so the correct way is to transfer it to BigDecimal. In addition, if you have a number of such functions and you do not want to write BigDecimal(value) everywhere, you can create an implicit conversion function as follows:

 implicit def intToBigDecimal(value: Int) = BigDecimal(value) 

and next time Scala will seamlessly convert all your Ints (including constants) to BigDecimal. In fact, most programming languages ​​use noiseless conversions from integers to decimals or even decimals to fractions (e.g. Lisps), so this seems like a very logical move.

0
source

All Articles