24.3. Wyrażenie either/or
W pliku EitherOr.scala zdefiniowany jest obiekt select, który pozwala na zastosowanie w programie konstrukcji składającej się ze słów either oraz or, pozwalającej na losowe wykonanie jednego z dwóch zdefiniowanych fragmentów kodu.
Plik EitherOr.scala: import scala.util.Random object select { def either[A](a: => A) = new { def or[B >: A](b: => B) = if (Random.nextBoolean) a else b } }
Poniższy przykład ilustruje sposób wykorzystania tej konstrukcji.
scala> import language.reflectiveCallsimport language.reflectiveCalls scala> select either "Hi" or "Hello"
res1: String = Hi scala> select either "Hi" or "Hello"
res2: String = Hello scala> select either Some(1) or None
res3: Option[Int] = None scala> select either Some(1) or None
res4: Option[Int] = Some(1)
Metoda either ma jeden parametr i zwraca obiekt implementujący
anonimową klasę, w której zdefiniowana jest metoda or. Metoda or,
podobnie jak either, ma jeden parametr. W metodzie or wywoływana
jest metoda Random.nextBoolean i w zależności od zwróconego przez
nią rezultatu, metoda or zwraca rezultat ewaluacji argumentu metody
either albo argumentu metody or. Wykorzystanie parametrów typu
oraz ograniczenia dolnego powoduje, że typem całego wyrażenia jest
wspólny nadtyp wyrażeń przekazanych metodom either i or. W
przypadku wyrażeń z wierszy
i
jest to String, a w przypadku
wyrażeń z wierszy
i
jest to Option[Int]. W powyższych
wyrażeniach wykorzystana została notacja infiksowa, dzięki czemu nie
trzeba było otaczać argumentów metod either i or nawiasami. Nazwa
obiektu select została specjalnie dobrana w taki sposób, aby
pasowała do słów either i or. Import z wiersza
jest użyty w celu
uniknięcia ostrzeżenia kompilacji.
Plik EitherOr.scala:
import scala.util.Random
object select {
def either[A](a: => A) = new {
def or[B >: A](b: => B) = if (Random.nextBoolean) a else b
}
}
