我有以下接口(interface):

interface UserRepository {
  fun role(codename: String): IO<Option<Role>>

  fun accessRights(roleId: Long): IO<List<AccessRight>>
}

现在尝试使用它来组成有效的操作,如下所示:
private fun retrieveRole(roleCodename: String): IO<Option<RoleTo>> =
  IO.fx {
    val role = userRepository.role(roleCodename).bind()
    role.map { r ->
      val ar = userRepository.accessRights(r.id).bind()
      RoleTo.of(r, ar)
    }
  }

代码无法在第二个绑定(bind)上编译(由于userRepository.accessRights(r.id).bind()是暂停函数,因此请调用bind。我如何正确地编写两个操作?我不明白为什么第一个绑定(bind)可以工作,但是第二个绑定(bind)不起作用,并且我不想让我的函数挂起还是我必须这样做?

最佳答案

这是一个常见的陷阱。如果您有Option<A>Either<E, A>并希望对其进行操作,那么您的第一个直觉是在代码块上使用它:

either.map { !someIO }

问题是没有涵盖left / none选项。您应该双方都采取行动,并在执行之前提取出IO。
!either.fold({ ioLogError(it) }, { someIo })

现在,从0.10开始,因为fold是内联函数,所以您也可以在其中使用!。我不能保证将来会如此,因为这是我们为方便起见而保留的内联的意外行为。

10-07 19:25
查看更多