You probably also thought about this idea, but what about this:
class StringOrIntOrDouble private(val first: Option[String], val second: Option[Int], val third: Option[Double]) {
def this(first: String) = this(Some(first), None, None)
def this(second: Int) = this(None, Some(second), None)
def this(third: Double) = this(None, None, Some(third))
def this(first: String, second: Int) = this(Some(first), Some(second), None)
def this(second: Int, third: Double) = this(None, Some(second), Some(third))
def this(first: String, third: Double) = this(Some(first), None, Some(third))
def this(first: String, second: Int, third: Double) = this(Some(first), Some(second), Some(third))
}
The main constructor private, so you cannot create an empty instance. Obviously, you could expand it with the implementation of Product, and equals, hashCode, toStringand other useful things as classes case (but beware copythat can easily break the invariant).
, , ( ), "" - - .
class TripleIor[+A, +B, +C] private(val first: Option[A], val second: Option[B], val third: Option[C]) {
}
object TripleIor {
def first[A](first: A) = new TripleIor[A, Nothing, Nothing](Some(first), None, None)
def second[B](second: B) = new TripleIor[Nothing, B, Nothing](None, Some(second), None)
def third[C](third: C) = new TripleIor[Nothing, Nothing, C](None, None, Some(third))
def firstAndSecond[A, B](first: A, second: B) = new TripleIor[A, B, Nothing](Some(first), Some(second), None)
def secondAndThird[B, C](second: B, third: C) = new TripleIor[Nothing, B, C](None, Some(second), Some(third))
def firstAndThird[A, C](first: A, third: C) = new TripleIor[A, Nothing, C](Some(first), None, Some(third))
def apply[A, B, C](first: A, second: B, third: C) = new TripleIor[A, B, C](Some(first), Some(second), Some(third))
}
, sealed trait 7 , , . , copy , ( ).
sealed trait TripleIor[A, B, C] extends Product {
def firstOption: Option[A]
def secondOption: Option[B]
def thirdOption: Option[C]
}
object TripleIor {
final case class First[A](first: A) extends TripleIor[A, Nothing, Nothing] {
override def firstOption: Option[A] = Some(first)
override def secondOption: Option[Nothing] = None
override def thirdOption: Option[Nothing] = None
}
final case class Second[B](second: B) extends TripleIor[Nothing, B, Nothing] {
override def firstOption: Option[Nothing] = None
override def secondOption: Option[B] = Some(second)
override def thirdOption: Option[Nothing] = None
}
final case class Third[C](third: C) extends TripleIor[Nothing, Nothing, C] {
override def firstOption: Option[Nothing] = None
override def secondOption: Option[Nothing] = None
override def thirdOption: Option[C] = Some(third)
}
final case class FirstSecond[A, B](first: A, second: B) extends TripleIor[A, B, Nothing] {
override def firstOption: Option[A] = Some(first)
override def secondOption: Option[B] = Some(second)
override def thirdOption: Option[Nothing] = None
}
final case class SecondThird[B, C](second: B, third: C) extends TripleIor[Nothing, B, C] {
override def firstOption: Option[Nothing] = None
override def secondOption: Option[B] = Some(second)
override def thirdOption: Option[C] = Some(third)
}
final case class FirstThird[A, C](first: A, third: C) extends TripleIor[A, Nothing, C] {
override def firstOption: Option[A] = Some(first)
override def secondOption: Option[Nothing] = None
override def thirdOption: Option[C] = Some(third)
}
final case class All[A, B, C](first: A, second: B, third: C) extends TripleIor[A, B, C] {
override def firstOption: Option[A] = Some(first)
override def secondOption: Option[B] = Some(second)
override def thirdOption: Option[C] = Some(third)
}
}
P.S. , - , , .