Created
June 10, 2017 20:18
-
-
Save Sciss/c2585eed77fca8c3a0bfbd1d54c41258 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| // cf. http://www.artima.com/scalazine/articles/stackable_trait_pattern.html | |
| trait Request { | |
| type Response | |
| } | |
| trait Context { | |
| def handle[R](req: Request { type Response = R }): R | |
| } | |
| object Foo extends Request { | |
| case class Response(i: Int) | |
| } | |
| object Bar extends Request { | |
| case class Response(s: String) | |
| } | |
| trait HandlesFoo extends Context { | |
| abstract override def handle[R](req: Request { type Response = R }): R = | |
| req match { | |
| case Foo => Foo.Response(123) | |
| case _ => super.handle(req) | |
| } | |
| } | |
| trait HandlesBar extends Context { | |
| abstract override def handle[R](req: Request { type Response = R }): R = | |
| req match { | |
| case Bar => Bar.Response("456") | |
| case _ => super.handle(req) | |
| } | |
| } | |
| // not possible: | |
| // object Attempt1 extends HandlesFoo | |
| trait FinallyFails extends Context { | |
| def handle[R](req: Request { type Response = R }): R = | |
| sys.error(s"Unsupported request $req") | |
| } | |
| object Attempt2 extends FinallyFails with HandlesFoo with HandlesBar | |
| object Baz extends Request { | |
| type Response = Unit | |
| } | |
| import scala.util.Try | |
| Try(Attempt2.handle(Baz)) | |
| Attempt2.handle(Foo) | |
| Attempt2.handle(Bar) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment