Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Either[ErrorResponse, X]
- Future[Either[ErrorResponse, X]]
- Option[ErrorResponse]
- type Parameters = Map[String, String]
- // allows me to flatmap on an either
- implicit def toRightProjection[Failure, Success](e: Either[Failure, Success]) =
- e.right
- // converts anything to a future
- implicit def toFuture[T](t: T) =
- Future.successful(t)
- // retrieves the request paramters from the given request
- def requestParameters(request: RequestHeader): Either[ErrorResponse, Parameters] = ???
- // retrieves the response type from the given parameters
- def responseType(p: Parameters): Either[ErrorResponse, String] = ???
- // retrieves the client id from the given parameters
- def clientId(p: Parameters): Either[ErrorResponse, String] = ???
- // retrieves the client using the given client id
- def client(clientId: String): Future[Either[ErrorResponse, Client]] = ???
- // validates the response type of the client
- def validateResponseType(client: Client, responseType: String): Option[ErrorResponse] = ???
- val result: Either[ErrorResponse, Future[Either[ErrorResponse, Client]]] =
- for {
- parameters <- requestParameters(request)
- clientId <- clientId(parameters)
- responseType <- responseType(parameters)
- } yield {
- val result: Future[Either[ErrorResponse, Either[ErrorResponse, Client]]] =
- for {
- errorOrClient <- client(clientId)
- client <- errorOrClient
- } yield validateResponseType(client, responseType).toLeft(client)
- result.map(_.joinRight)
- }
- val wantedResult: Future[Either[ErrorResponse, Client]] =
- result.left.map(Future successful Left(_)).merge
- val result: Future[Either[ErrorResponse, Client]] =
- for {
- parameters <- requestParameters(request)
- clientId <- clientId(parameters)
- responseType <- responseType(parameters)
- client <- client(clientId)
- _ <- validateResponseType(client, responseType)
- }
- import scalaz._, Scalaz._
- implicit val futureMonad = new Monad[Future] {
- override def point[A](a: ⇒ A): Future[A] = future(a)
- override def bind[A, B](fa: Future[A])(f: A ⇒ Future[B]): Future[B] =
- fa.flatMap(f)
- }
- import EitherT._
- val result: EitherT[Future, ErrorResponse, Client] =
- for {
- parameters <- fromEither(Future(requestParameters(request)))
- clientId <- fromEither(Future(clientId(parameters)))
- responseType <- fromEither(Future(responseType(parameters)))
- client <- fromEither(client(clientId))
- response <- fromEither[Future, ErrorResponse, Client](Future(validateResponseType(client, responseType).toLeft(client)))
- } yield response
- val x: Future[/[ErrorResponse, Client]] = result.run
- `scala.util.Either` is not a Monad, but the scalaz library has a great implementation.
- object Test extends ToIdOps {
- import scalaz.{ Monad, Functor, EitherT, /, -/, /- }
- import scalaz.syntax.ToIdOps
- implicit val FutureFunctor = new Functor[Future] {
- def map[A, B](a: Future[A])(f: A => B): Future[B] = a map f
- }
- implicit val FutureMonad = new Monad[Future] {
- def point[A](a: => A): Future[A] = Future(a)
- def bind[A, B](fa: Future[A])(f: (A) => Future[B]): Future[B] = fa flatMap f
- }
- def someMethod: Future[/[InvalidData, ValidData]] = {
- // things went well
- ValidData.right // this comes from ToIdOps
- // or something went wrong
- InvalidData.left
- }
- def someOtherMethod: Future[/[InvalidData, ValidData]] // same as above
- val seq = for {
- d <- EitherT(someMethod)
- y <- EitherT(someOtherMethod)
- } yield { // whatever}
- // you can now Await.result(seq.run, duration)
- // you can map or match etc with /- and -/
- val result = seq.run map {
- case -/(left) => // invalid data
- case /-(right) => // game on
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement