An Option class in Scala with three states: Unknown, Known.Some, Known.None
Scala's library includes a class called Option which can be used to represent an optional value, instead of using null, it has two states: None and Some[T], so either it has a value, or it doesn't.
I needed a class to represent three states (tristate): Unknown (you don't know the value), Known.Some (you know the value), Known.None (you know there is no value). An example of where you'd use this might be for a property like radioType of class car. You might use a tristate value to indicate that you don't know the type of the radio on this car, or that you do know the type of radio, or that there is no radio.
Code:
/*
* Similar to Option[T], but represents three states: known-some, known-none, and unknown
*/
sealed abstract class KnownUnknown[+T] extends Product {
def isEmpty : Boolean
def get : T
def isDefined : Boolean = !isEmpty
}
/*
* Represents the unknown state
*/
case object Unknown extends KnownUnknown[ Nothing ] {
def isEmpty = true
def get = throw new NoSuchElementException("Unknown.get")
}
/*
* Represents the known state (either you know its Some(T) or its None)
*/
final case class Known[+T](_value : Option[T]) extends KnownUnknown[T] {
if ( _value == null )
throw new NullPointerException
def this(value : T) = this(Some(value))
def isEmpty = false
def get = _value.get
}
And a few basic tests:
class KnownUnknownTest extends TestCase("KnownUnknown") {
def testSome = {
var value : KnownUnknown[Int] = null
value = new Known(5)
value match {
case Known(known) =>
known match {
case Some(number) => assertEquals(5, number)
case None => fail()
}
case Unknown => fail()
}
assertEquals(5, value.get)
}
def testNone = {
var value : KnownUnknown[Int] = null
value = new Known(None)
value match {
case Known(known) =>
known match {
case Some(number) => fail()
case None => // good
}
case Unknown => fail()
}
try {
value.get
}
catch {
case e:NoSuchElementException => // good
case _ => fail()
}
assert(true) // so we get picked up as a test
}
def testUnknown = {
var value : KnownUnknown[Int] = null
value = Unknown
value match {
case Known(known) => fail()
case Unknown => // good
}
try {
value.get
}
catch {
case e:NoSuchElementException => // good
case _ => fail()
}
assert(true) // so we get picked up as a test
}
}
Comments [0]