【发布时间】:2019-09-21 09:19:51
【问题描述】:
我在我的 Kotlin 后端项目中使用 Arrow。我有这样的存储库:
interface UserRepository {
fun user(username: String): Try<Option<User>>
}
现在我想更进一步,从具体的Try 类型中抽象出来,而是返回Kind<F, Option<User>>。我可以用这段代码做到这一点:
interface UserRepository<F> {
fun user(username: String): Kind<F, Option<User>>
}
class IdRepository : UserRepository<ForId> {
fun user(username: String): Kind<ForId<Option<User>>> =
if (username == "known") Id.just(Some(User()))
else Id.just(None)
}
但现在我很难使用它。我不明白我们怎么能说userRepository 中的F 必须是Monad,这样它才能在monad 理解块中使用。假设我有一些这样定义的类:
class UserService<F>(ME: MonadError<F, Throwable>, repo: UserRepository<F>)
: MonadError<F, Throwable> by ME {
fun someOperations(username: String) : Kind<F, User> = bindingCatch {
val (user) = repo.user(username)
user.fold({ /* create user */ }, { /* return user */ })
}
}
编译器抱怨它无法在repo.user 上绑定user,因为它需要Kind<ForTry, ...>,但repo.user 返回Kind<F, ...>,此处未知。如何正确实现从 Try 的抽象,以便我可以使用 Id 实例实现存储库以及如何在服务类中使用此类存储库?
【问题讨论】: