Котлин стрелка объединить список проверенных - PullRequest
2 голосов
/ 06 июля 2019

У меня есть следующие классы:

class Person(id: Long, name: String)

sealed class PersonError {
    data class InvalidId(val field: String) : PersonError()
    data class InvalidName(val field: String) : PersonError()
}

Когда я проверяю и проверяю несколько человек, я получаю:

List<ValidatedNel<Error, Person>>

или:

List<Validated<Error, Person>>

Как преобразовать приведенный выше список в:

Validated<Nel<MappingError>, List<Person>>

Я хочу накапливать все ошибки, связанные с проверкой всех лиц.Это необходимо, потому что я хочу сделать следующее:

val vId : ValidatedNel<Error, Long> = validateId(id).toValidatedNel()
val vPersons : List<ValidatedNel<Error, Person>> = validatePersons(persons).toValidatedNel()

ValidatedNel.applicative<Nel<PersonError>>(Nel.semigroup<PersonError>())
    .map(vId, vPersons) {
        val id = it.a
        val persons = it.b
        Group(id, persons)
    }.fix()

Текущая карта не принимает List<ValidatedNel<Error>, Person>>

1 Ответ

0 голосов
/ 08 июля 2019

Для левой части Validated требуется Semigroup для сбора всех ошибок; для правой стороны вашего Validated требуется product (поскольку Group(a, b) - это тип продукта); и накопление ошибок в конкретном человеке требует sequence (или traverse с функцией идентификации), чтобы собрать все ошибки для данного человека, поэтому должно работать следующее:

        val SE = Nel.semigroup<PersonError>()

        val validatedGroup: ValidatedNel<PersonError, Group> = vId.product(
                SE,
                vPersons.sequence(ValidatedNel.applicative(SE)).fix().map { it.fix() }
        ).map(::Group.tupled2())

Я думаю, что в следующей версии Arrow вызовы fix () будут сведены к минимуму или устранены, так что, надеюсь, .fix().map { it.fix() } может быть скоро удален.

...