This answer to a similar question about Promise[Option[A]]
might help. Just substitute Future
for Promise
.
I'm inferring the following types for getUserDetails
and getSchool
from your question:
getUserDetails: UserID => Future[Either[??, UserDetails]]
getSchool: SchoolID => Future[Option[School]]
Since you ignore the failure value from the Either
, transforming it to an Option
instead, you effectively have two values of type A => Future[Option[B]]
.
Once you've got a Monad
instance for Future
(there may be one in scalaz, or you could write your own as in the answer I linked), applying the OptionT
transformer to your problem would look something like this:
for {
ud <- optionT(getUserDetails(user.userID) map (_.right.toOption))
sid <- optionT(Future.successful(ud.schoolID))
s <- optionT(getSchool(sid))
} yield s
Note that, to keep the types compatible, ud.schoolID
is wrapped in an (already completed) Future.
The result of this for-comprehension would have type OptionT[Future, SchoolID]
. You can extract a value of type Future[Option[SchoolID]]
with the transformer's run
method.