Для понимания с библиотекой kotlin и arrow-kt - PullRequest
0 голосов
/ 12 декабря 2018

Я использую библиотеку arrow-kt и пытаюсь использовать Either и IO в одном и том же для понимания.

Скажем, у меня есть следующий фрагмент кода:

IO.monad().binding {
    val ans: Either<Error, Data> = someFunctionThatReturnsEitherWrappedInIO().bind()
}

Теперь я хотел бы использовать привязку к ans:

val data: Data = ans.bind() // My intent

Возможно ли сделать это в рамках первой части кода?

В настоящее времяЯ пытаюсь вложить привязку Either в область привязки ввода-вывода, но я не уверен, что это хорошая практика:

IO.monad().binding {
    val ans: Either<Error, Data> = someFunctionThatReturnsEitherWrappedInIO().bind()
    val ansB: Either<Error, OtherData> = someOtherFunctionThatReturnsEitherWrappedInIO().bind()

    val newData: Either<Any, NewData> = Either.monad<Any>().binding {
        val data: Data = ans.bind()
        val otherData: OtherData = ansB.bind()
        NewData(data.a, otherData.lala)
    }.fix()
}

1 Ответ

0 голосов
/ 12 декабря 2018

Фон

Сначала я должен упомянуть, что Монады не составляют , поэтому вам необходим Монадный преобразователь , в вашем случае EitherT - это парень, который может вам помочь.

Пример

object Error

fun one() = IO { Right(1) }
fun two() = IO { Right("2") }
fun toInt(str: String) = IO { Try { str.toInt() }.toEither { Error } }

val result: IO<Either<Error, Int>> =
    EitherT.monad<ForIO, Error>(IO.monad()).binding {
        val oneInt = EitherT(one()).bind()
        val twoString = EitherT(two()).bind()
        val twoInt = EitherT(toInt(twoString)).bind()
        oneInt + twoInt
    }.value().fix()

println(result.unsafeRunSync()) // Just for demonstration, don't do this ever

Справа (b = 3)

...