Skip to content

Instantly share code, notes, and snippets.

@futurechimp
Created February 27, 2012 22:17
Show Gist options
  • Save futurechimp/1927503 to your computer and use it in GitHub Desktop.
Save futurechimp/1927503 to your computer and use it in GitHub Desktop.
The Conundrum
/* Here's the first way, the "view" version: When your code calls request.pathInfo, the compiler says,
"HttpServletRequest doesn't have pathInfo. But it can implicitly convert to RichRequest.
I'm going to call RichRequest.servletRequestToRichRequest, and then call pathInfo on the result of that." */
class RichRequest(req: HttpServletRequest) extends Request {
def pathInfo = req.getPathInfo
}
object RichRequest {
implicit def servletRequestToRichRequest(req: HttpServletRequest) = new RichRequest(request)
}
/* Here's the other way, using type classes: */
trait Request[A] {
def pathInfo(implicit a: A): String
}
object Request {
implicit val servletRequset = new Request[HttpServletRequest] {
def pathInfo(req: HttpServletRequest) = req.getPathInfo
}
}
/* A *Request* is a *class of types* that knows how to perform certain operations over other types.
(If you want to impress the ladies at the bar, call it "ad hoc polymorphism.") Now ScalatraServlet is
amended to look like this: */
trait ScalatraServlet {
def request: HttpServletRequest // blech
val betterRequest: Request[HttpServletRequest] // Hooray
}
// then we use betterRequest.pathInfo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment