В качестве альтернативы примеру Scalaz отсутствующего фактора, если вы действительно хотите суммировать список объектов (в отличие от сопоставления каждого из них с числом и последующего суммирования этих чисел), скаляр поддерживает это также .
Это зависит от рассматриваемого класса, для которого определен экземпляр Моноид (что на практике означает, что он должен иметь Ноль и Полугруппа определены). Моноид можно рассматривать как более слабое обобщение основной черты характера скалы Numeric
специально для суммирования; в конце концов, если вы можете определить нулевой элемент и способ добавить / объединить два элемента, то у вас есть все, что вам нужно, чтобы получить сумму нескольких объектов.
Логика Scalaz точно такая же, как и при суммировании целых чисел вручную - list.foldLeft(0) { _ + _ }
- за исключением того, что Zero
предоставляет начальный нулевой элемент, а Semigroup
обеспечивает реализацию +
(называемая append
).
Это может выглядеть примерно так:
import scalaz._
import Scalaz._
// Define Monoid for Blah
object Blah {
implicit def zero4Blah: Zero[Blah] = zero(Blah("", 0))
implicit def semigroup4Blah: Semigroup[Blah] = semigroup { (a, b) =>
// Decide how to combine security names - just append them here
Blah(a.security + b.security, a.price + b.price)
}
}
// Now later in your class
val myList = List(Blah("a", 2.0), Blah("b", 4.0))
val mySum = myList.asMA.sum
В этом случае mySum
фактически будет экземпляром Бла, равным Blah("ab", 6.0)
, а не просто двойником.
ОК, в этом конкретном примере вы на самом деле не так много получаете, потому что получение «суммы» имен безопасности не очень полезно. Но для других классов (например, если у вас есть количество, а также цена или несколько соответствующих свойств), это может быть очень полезно. По большому счету замечательно, что если вы можете определить какой-то способ добавления двух экземпляров вашего класса вместе, вы можете рассказать об этом скалазу (определив Semigroup
); и если вы также можете определить нулевой элемент, вы можете использовать это определение для простого суммирования коллекций вашего класса.