I have just started with Scala, and I'm trying to create a data type, which is a union of Integers and the special values Infinity and -Infinity. I'm trying to figure out how to do this the most idiomatic way in Scala.
One option I've tried so far is by using a trait:
trait MySet
case object Infinity extends MySet
case object NegInfinity extends MySet
case class Value(value: Int) extends MySet
This seams to work, but I'm not sure if this is the smartest way of doing it. In the end, I want to use this to model algebraic structures such as Groups, Monoids, etc. with MySet as the carrier set. E.g. doing something like:
trait Monoid[T]:
val zero: T
def @ (x: T, y: T): T
Something in that direction.
Thanks for all suggestions!
CodePudding user response:
As Luis said in the comment, make the trait
sealed
will make it so that the compiler will know what are the possible extentions of MySet
Otherwise, your monoid can be enriched with the following operations :
val mySetMonoid = new Monoid[MySet] {
// 1) first the associative operation, which I guess would be
def op(a1: MySet, a2: MySet) = (a1, a2) match {
case (Value(x), Value(y)) => x y
case (Value(_), Infinity) => Infinity
case (Value(_), NegInfinity) => NegInfinity
case (Infinity, Value(_)) => Infinity
case (NegInfinity, Value(_)) => NegInfinity
case (NegInfinity, Infinity) => throw new UnsupportedOperationException(..)
// here you need to be more specific
// on how you want to handle infinity
// and -infinity being added
}
// 2) then the definition of your zero in regard of the associative operation
val zero = Value(0)
}