Last active
July 21, 2020 19:23
-
-
Save igstan/88d44b0d97e7b8e8bf1f0bbdc3c49cff to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait Optional[A] { | |
def visit[R](visitor: Optional.Visitor[A, R]): R | |
// Alias to show that visiting is similar to pattern matching. | |
def matching[R](visitor: Optional.Visitor[A, R]): R = | |
visit(visitor) | |
} | |
object Optional { | |
// Lists all the cases that must be handled when visiting. | |
// | |
// In the standard Visitor pattern, these two methods would have been | |
// called `visit(a: Some)` and `visit(a: None)`. I find the version | |
// below way nicer. | |
trait Visitor[A, R] { | |
def none: R | |
def some(value: A): R | |
} | |
/** Factory method for None values. */ | |
def none[A]: Optional[A] = | |
new Optional[A] { | |
override def visit[R](visitor: Optional.Visitor[A, R]) = | |
visitor.none | |
} | |
/** Factory method for Some values. */ | |
def some[A](value: A): Optional[A] = | |
new Optional[A] { | |
override def visit[R](visitor: Optional.Visitor[A, R]) = | |
visitor.some(value) | |
} | |
} | |
object Example { | |
def main(args: Array[String]): Unit = { | |
val optional: Optional[Int] = Optional.some(1) | |
val result = | |
optional.matching(new Optional.Visitor[Int, String] { | |
override def none = | |
"none" | |
override def some(value: Int) = | |
s"some($value)" | |
}) | |
println(s"result: $result") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment