Advertisement
Guest User

Untitled

a guest
Jul 23rd, 2014
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.57 KB | None | 0 0
  1. Either[ErrorResponse, X]
  2. Future[Either[ErrorResponse, X]]
  3. Option[ErrorResponse]
  4.  
  5. type Parameters = Map[String, String]
  6.  
  7. // allows me to flatmap on an either
  8. implicit def toRightProjection[Failure, Success](e: Either[Failure, Success]) =
  9. e.right
  10.  
  11. // converts anything to a future
  12. implicit def toFuture[T](t: T) =
  13. Future.successful(t)
  14.  
  15. // retrieves the request paramters from the given request
  16. def requestParameters(request: RequestHeader): Either[ErrorResponse, Parameters] = ???
  17.  
  18. // retrieves the response type from the given parameters
  19. def responseType(p: Parameters): Either[ErrorResponse, String] = ???
  20.  
  21. // retrieves the client id from the given parameters
  22. def clientId(p: Parameters): Either[ErrorResponse, String] = ???
  23.  
  24. // retrieves the client using the given client id
  25. def client(clientId: String): Future[Either[ErrorResponse, Client]] = ???
  26.  
  27. // validates the response type of the client
  28. def validateResponseType(client: Client, responseType: String): Option[ErrorResponse] = ???
  29.  
  30. val result: Either[ErrorResponse, Future[Either[ErrorResponse, Client]]] =
  31. for {
  32. parameters <- requestParameters(request)
  33. clientId <- clientId(parameters)
  34. responseType <- responseType(parameters)
  35. } yield {
  36. val result: Future[Either[ErrorResponse, Either[ErrorResponse, Client]]] =
  37. for {
  38. errorOrClient <- client(clientId)
  39. client <- errorOrClient
  40. } yield validateResponseType(client, responseType).toLeft(client)
  41.  
  42. result.map(_.joinRight)
  43. }
  44.  
  45. val wantedResult: Future[Either[ErrorResponse, Client]] =
  46. result.left.map(Future successful Left(_)).merge
  47.  
  48. val result: Future[Either[ErrorResponse, Client]] =
  49. for {
  50. parameters <- requestParameters(request)
  51. clientId <- clientId(parameters)
  52. responseType <- responseType(parameters)
  53. client <- client(clientId)
  54. _ <- validateResponseType(client, responseType)
  55. }
  56.  
  57. import scalaz._, Scalaz._
  58.  
  59. implicit val futureMonad = new Monad[Future] {
  60. override def point[A](a: ⇒ A): Future[A] = future(a)
  61.  
  62. override def bind[A, B](fa: Future[A])(f: A ⇒ Future[B]): Future[B] =
  63. fa.flatMap(f)
  64. }
  65.  
  66. import EitherT._
  67. val result: EitherT[Future, ErrorResponse, Client] =
  68. for {
  69. parameters <- fromEither(Future(requestParameters(request)))
  70. clientId <- fromEither(Future(clientId(parameters)))
  71. responseType <- fromEither(Future(responseType(parameters)))
  72. client <- fromEither(client(clientId))
  73. response <- fromEither[Future, ErrorResponse, Client](Future(validateResponseType(client, responseType).toLeft(client)))
  74. } yield response
  75.  
  76. val x: Future[/[ErrorResponse, Client]] = result.run
  77.  
  78. `scala.util.Either` is not a Monad, but the scalaz library has a great implementation.
  79.  
  80. object Test extends ToIdOps {
  81.  
  82. import scalaz.{ Monad, Functor, EitherT, /, -/, /- }
  83. import scalaz.syntax.ToIdOps
  84.  
  85. implicit val FutureFunctor = new Functor[Future] {
  86. def map[A, B](a: Future[A])(f: A => B): Future[B] = a map f
  87. }
  88.  
  89. implicit val FutureMonad = new Monad[Future] {
  90. def point[A](a: => A): Future[A] = Future(a)
  91. def bind[A, B](fa: Future[A])(f: (A) => Future[B]): Future[B] = fa flatMap f
  92. }
  93. def someMethod: Future[/[InvalidData, ValidData]] = {
  94. // things went well
  95. ValidData.right // this comes from ToIdOps
  96. // or something went wrong
  97. InvalidData.left
  98. }
  99. def someOtherMethod: Future[/[InvalidData, ValidData]] // same as above
  100. val seq = for {
  101. d <- EitherT(someMethod)
  102. y <- EitherT(someOtherMethod)
  103. } yield { // whatever}
  104. // you can now Await.result(seq.run, duration)
  105. // you can map or match etc with /- and -/
  106. val result = seq.run map {
  107. case -/(left) => // invalid data
  108. case /-(right) => // game on
  109. }
  110. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement