I have the following code that represents a GF2 field:
trait GF2 { def unary_- = this def + (that: GF2): GF2 def * (that: GF2): GF2 def / (that: GF2) = that match { case Zero => throw new IllegalArgumentException("Div by 0") case _ => this } } object Zero extends GF2 { override def toString = "Zero" def + (that: GF2) = that def * (that: GF2) = this } object One extends GF2 { override def toString = "One" def + (that: GF2) = that match { case One => Zero ; case _ => this } def * (that: GF2) = that match { case One => this ; case _ => that } }
And now I would like to call this function: List(One, One, Zero, One).sumto be GF2._+called for summation, how can I do this? Should I GF2extend any interface or should I use a type class method?
List(One, One, Zero, One).sum
GF2._+
GF2
You need a numeric [GF2] implicit:
trait GF2IsNumeric extends Numeric[GF2] { def plus(x: GF2, y: GF2): GF2 = x + y def minus(x: GF2, y: GF2): GF2 = x + (-y) def times(x: GF2, y: GF2): GF2 = x * y def negate(x: GF2): GF2 = -x def fromInt(x: Int): GF2 = ??? def toInt(x: GF2): Int = ??? def toLong(x: GF2): Long = ??? def toFloat(x: GF2): Float = ??? def toDouble(x: GF2): Double = ??? override def zero = Zero override def one = One } trait GF2Ordering extends scala.math.Ordering[GF2] { override def compare(a: GF2, b: GF2) = if (a == b) 0 else if (b == One) 1 else -1 } implicit object GF2IsNumeric extends GF2IsNumeric with GF2Ordering
Then you can do:
println(List(One, One, Zero, One).sum) // One
Look at the signature sum:
sum
def sum[B >: A](implicit num: Numeric[B]): B
, GF2 Numeric, Numeric[GF2], Numeric , , , .
Numeric
Numeric[GF2]
, , sum typeclass (, ?).
, , ( Numeric) - reduce ( ), fold:
reduce
fold
yourList.reduce(_ + _) yourList.fold(Zero)(_ + _)
Numeric , . . , .
object InScope{ implicit object GF2Numeric extends Numeric[GF2]{ //..your implementation here } }
The full signature sumon a Listactually is:
List
def sum(implicit num: Numeric[A])
Where Ais the type List[A].
A
List[A]