I´ve been watching some examples of monads transformers with Cats
, and I was trying to reproduce those in Scalaz
Here I have a for comprehension where I first receive an optional which I flatMap with OptionalT
, and the second function return a Future of Employee.
Here my code
//Attributes for this example
sealed trait Employee {
val id: String
}
final case class EmployeeWithoutDetails(id: String) extends Employee
final case class EmployeeWithDetails(id: String, name: String, city: String, age: Int) extends Employee
case class Company(companyName: String, employees: List[EmployeeWithoutDetails])
trait HybridDBOps {
protected def getDetails(employeeId: String): Future[EmployeeWithDetails]
protected def getCompany(companyName: String): Option[Company]
}
class DbHybrid extends HybridDBOps {
override def getDetails(employeeId: String): Future[EmployeeWithDetails] = Future {
EmployeeWithDetails("1", "name", "city", 36)
}
override def getCompany(companyName: String): Option[Company] = Some(Company(companyName, List(EmployeeWithoutDetails("1"))))
}
def getEmployeeAgeScalaZHybrid(employeeId: String, companyName: String): Future[Option[Int]] = {
val db = new DbHybrid
val eventualOption = (for {
company <- OptionT.fromOption(db.getCompany(companyName)) --> Wont compile
if company.employees map (_.id) contains employeeId
details <- OptionT.liftF(db.getDetails(employeeId)) --> Wont compile
} yield details.age).run
eventualOption
}
This code is from cats version, and in scalaz the OptionT.fromOption
to wrap a Option does not exist, I notice that I can do OptionT(Some(db.getCompany(companyName))
and then compile but now the signature of the method says that I returning an Optional instead of a future.
Also how can use the OptionT.liftF
in ScalaZ
Here the complete example https://github.com/politrons/reactiveScala/blob/master/scala_features/src/main/scala/app/impl/scalaz/MonadTransformer.scala
Regards.
These should work as substitutes:
import scalaz.std.future._
import scalaz.syntax.monad._
// instead of OptionT.fromOption(db.getCompany(companyName))
OptionT(db.getCompany(companyName).pure[Future])
// instead of OptionT.liftF(db.getDetails(employeeId))
db.getDetails(employeeId).liftM[OptionT]
However, it would be good to have both methods also on OptionT
. You could add them and open a pull request.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.