首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在arrow-kt中从Try中抽象

如何在arrow-kt中从Try中抽象
EN

Stack Overflow用户
提问于 2019-09-21 07:16:27
回答 1查看 252关注 0票数 0

我在我的Kotlin后端项目中使用Arrow。我有这样的存储库:

代码语言:javascript
复制
interface UserRepository {
  fun user(username: String): Try<Option<User>>
}

现在我想更进一步,通过返回Kind<F, Option<User>>从具体的Try类型中抽象出来。我可以用下面的代码来实现:

代码语言:javascript
复制
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理解块中使用。假设我有一些定义如下的类:

代码语言:javascript
复制
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实例实现存储库,以及如何在服务类中使用这样的存储库?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-21 09:19:52

在0.10.0中,你可以使用Fx类型的类来执行monad绑定。它的变体是可用的,如您的示例上的kdoc中所述,其中每个变体代表您想要的能力级别。实际上,由于特效只能完全封装在IO中,因此大多数应用程序都使用IO.fx。如果您正在处理副作用,那么您只能替换支持挂起的运行时,所以这基本上将您的运行时选项缩小到Async<F>实例,因为挂起意味着潜在的异步工作。即IO、Rx等。但也永远不要尝试...这些对于急切、无效的纯计算是很好的。

代码语言:javascript
复制
/**
 * Fx allows you to run pure sequential code as if it was imperative.
 *
 * @see [arrow.typeclasses.suspended.monad.Fx] // Anything with flatMap
 * @see [arrow.typeclasses.suspended.monaderror.Fx] //Try, Either etc stop here
 * @see [arrow.fx.typeclasses.suspended.monaddefer.Fx] // IO
 * @see [arrow.fx.typeclasses.suspended.concurrent.Fx] // IO
 */
class UserService<F>(ME: MonadError<F, Throwable>, repo: UserRepository<F>) 
  : MonadError<F, Throwable> by ME {

  fun someOperations(username: String) : Kind<F, User> = 
    fx.monadThrow {
      val user = !repo.user(username)
      user.fold({ /* create user */ }, { /* return user */ })
    }
  }

}

如果您想了解更详细的解释,请访问https://slack.kotlinlang.org #箭头频道,我们将很乐意提供帮助,并在Kotlin中讨论FP

干杯!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58036032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档