OptionalT fromOptional 和 ScalaZ 中的 liftF
OptionalT fromOptional and liftF in ScalaZ
我一直在用 Cats
观看一些 monads 转换器的例子,我试图在 Scalaz
中重现这些例子
这里我有一个理解,我首先收到一个可选的,我用 OptionalT
进行 flatMap,第二个函数 return 是员工的未来。
这是我的代码
//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
}
此代码来自 cats 版本,在 scalaz 中 OptionT.fromOption
包装选项不存在,我注意到我可以执行 OptionT(Some(db.getCompany(companyName))
然后编译,但现在方法的签名说我 return 使用可选而不是未来。
还有如何在ScalaZ
中使用OptionT.liftF
此致。
这些应该可以作为替代品:
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]
不过,最好在 OptionT
上同时使用这两种方法。您可以添加它们并打开拉取请求。
我一直在用 Cats
观看一些 monads 转换器的例子,我试图在 Scalaz
这里我有一个理解,我首先收到一个可选的,我用 OptionalT
进行 flatMap,第二个函数 return 是员工的未来。
这是我的代码
//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
}
此代码来自 cats 版本,在 scalaz 中 OptionT.fromOption
包装选项不存在,我注意到我可以执行 OptionT(Some(db.getCompany(companyName))
然后编译,但现在方法的签名说我 return 使用可选而不是未来。
还有如何在ScalaZ
OptionT.liftF
此致。
这些应该可以作为替代品:
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]
不过,最好在 OptionT
上同时使用这两种方法。您可以添加它们并打开拉取请求。