scala - 将 F[A] 转换为 Future[A]
问题描述
我有一个存储库:
trait CustomerRepo[F[_]] {
def get(id: Identifiable[Customer]): F[Option[CustomerWithId]]
def get(): F[List[CustomerWithId]]
}
我有一个使用 Cats IO 的数据库实现,所以我有一个CustomerRepoPostgres[IO]
.
class CustomerRepoPostgres(xa: Transactor[IO]) extends CustomerRepo[IO] {
import doobie.implicits._
val makeId = IO {
Identifiable[Customer](UUID.randomUUID())
}
override def get(id: Identifiable[Customer]): IO[Option[CustomerWithId]] =
sql"select id, name, active from customer where id = $id"
.query[CustomerWithId].option.transact(xa)
override def get(): IO[List[CustomerWithId]] =
sql"select id, name, active from customer"
.query[CustomerWithId].to[List].transact(xa)
}
现在,我想使用一个不能处理任意持有者类型的库(它只支持Future
)。所以我需要一个CustomerRepoPostgres[Future]
.
我想写一些可以将我转换为的桥接CustomerRepoPostgres[IO]
代码CustomerRepoPostgres[Future]
:
class RepoBridge[F[_]](repo: CustomerRepo[F])
(implicit convertList: F[List[CustomerWithId]] => Future[List[CustomerWithId]],
convertOption: F[Option[CustomerWithId]] => Future[Option[CustomerWithId]]) {
def get(id: Identifiable[Customer]): Future[Option[CustomerWithId]] = repo.get(id)
def get(): Future[List[CustomerWithId]] = repo.get()
}
我不喜欢这种方法对存储库中使用的每种类型都需要隐式转换器。有一个更好的方法吗?
解决方案
这正是无标签最终方法的用途,F
通过要求它遵循一些特定的类型约束来抽象。例如,让我们创建一个自定义实现,它需要F
是Applicative
:
trait CustomerRepo[F[_]] {
def get(id: Identifiable[Customer]): F[Option[CustomerWithId]]
def get(): F[List[CustomerWithId]]
}
class CustorRepoImpl[F[_]](implicit A: Applicative[F]) extends CustomerRepo[F] {
def get(id: Identifiable[Customer]): F[Option[CustomerWithId]] {
A.pure(???)
}
def get(): F[List[CustomerWithId]] = {
A.pure(???)
}
}
这样,无论 的具体类型是F
什么,如果它有一个实例,Applicative[F]
那么你就可以开始了,无需定义任何转换器。
我们这样做的方式只是F
根据我们需要做的处理,把相关的约束放在上面。如果我们需要顺序计算,我们可以使用 a Monad[F]
,然后flatMap
使用结果。如果不需要顺序性,则Applicative[F]
可能足够强大。
推荐阅读
- .net - 如何配置 Cosmos DB .NET 3.0 SDK 以使用驼峰式案例进行序列化?
- r - R中多个符号之前的gsub字符串
- python - 使用python授权的问题
- sql - 如何在没有 to_char 的情况下将日期转换为 YYYY-MM
- react-native - 如何过滤 Flatlist 上的项目?
- python - 气流 HdfsSensor hdfs_conn_id
- python - 如何结帐分行
- excel - 如何使用 VBA 导入 .txt 文件并将导入的 .txt 文件名添加到 Excel 工作表的单独单元格中
- visual-studio - 在 Visual Studio 中悬停时如何显示变量类型
- c++ - 如何分离和保护文本块并在之后打开它们?C++