我在我的 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)
}
但现在我正在努力使用它。我不明白我们怎么能说F
inuserRepository
必须是一个 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 */ })
}
}
编译器抱怨它不能user
在线绑定,repo.user
因为它需要Kind<ForTry, ...>
但是这里未知的repo.user
返回。Kind<F, ...>
如何正确实现抽象,Try
以便我可以使用Id
实例实现存储库以及如何在服务类中使用此类存储库?