How to use IO compositions in arrow-kt within sync context

六眼飞鱼酱① 提交于 2021-01-28 07:44:46

问题


I have following interfaces:

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

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

Now trying to use it to compose effectfful operations like this:

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)
    }
  }

The code fails to compile on the second bind (call to userRepository.accessRights(r.id).bind() since bind is suspend function. How I can properly compose two operations? I don't get why first bind works but second doesn't and I don't want to make my function suspend or I have to do it anyway?


回答1:


This is one frequent gotcha. If you have Option<A> or Either<E, A> and you'd like to act on it, your first instinct is to use it on the block:

either.map { !someIO }

The problem is that the left/none option isn't covered. You should act on both sides, and extract out the IO before executing it.

!either.fold({ ioLogError(it) }, { someIo })

For now, as of 0.10, because fold is an inline function you can use ! inside it too. I cannot promise that'll be the case in the future, as this is an unintended behavior of inline that we left for convenience.




回答2:


I was able to solve issue using traverse and applicative instance of IO:

private fun retrieveRole(roleCodename: String): IO<Option<RoleTo>> =
  IO.fx {
    val role = userRepository.role(roleCodename).bind()
    val accessRights = role.traverse(IO.applicative()) {
      userRepository.accessRights(it.id)
    }.bind()
    role.map2(accessRights) {
      (r, ar) -> RoleTo.of(r, ar)
    }
  }

Thanks for pointing out about the fact that map expects pure functions.



来源:https://stackoverflow.com/questions/58039277/how-to-use-io-compositions-in-arrow-kt-within-sync-context

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!