Как использовать композиции ввода-вывода в arrow-kt в контексте синхронизации - PullRequest
0 голосов
/ 21 сентября 2019

У меня есть следующие интерфейсы:

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

Код не компилируется при втором связывании (вызовuserRepository.accessRights(r.id).bind(), поскольку bind - это функция приостановки. Как правильно составить две операции? Я не понимаю, почему первое связывание работает, а второе - нет, и я не хочу, чтобы моя функция приостанавливалась, или я должен это сделатьв любом случае?

Ответы [ 2 ]

1 голос
/ 22 сентября 2019

Мне удалось решить проблему, используя traverse и аппликативный экземпляр 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)
    }
  }

Спасибо, что указали на тот факт, что map ожидает чистые функции.

1 голос
/ 22 сентября 2019

Это одна частая ошибка.Если у вас есть Option<A> или Either<E, A>, и вы хотите воздействовать на него, ваш первый инстинкт - использовать его в блоке:

either.map { !someIO }

Проблема в том, что опция left / none не активна.не покрыто.Вы должны действовать с обеих сторон и извлечь IO перед его выполнением.

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

На данный момент, с 0.10, потому что fold является встроенной функцией, вы можете использовать ! внутри нее тоже.Я не могу обещать, что так будет и в будущем, так как это непреднамеренное поведение inline, которое мы оставили для удобства.

...