Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ior mapOrAccumulate #3472

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

sampengilly
Copy link
Contributor

Add support for mapOrAccumulate functions which when run inside an IorRaise scope accumulate errors into a Both case with the combined errors and any successfully mapped items.

This change adds the basic mapOrAccumulate functions, it doesn't provide any additional convenience functions like those which take an Iterable<T> receiver such as those found in Iterable.kt. As I see it, in order to provide those functions we'd either need to wait for context parameters, or move each of those existing functions into the Raise interface and define the new ones in the IorRaise class.

I also haven't included the zipOrAccumulate functions in this change. I intend to do those as it feels like a use case which makes sense (carry out N operations, collect the errors, but if some succeeded then treat it as a success overall).

@sampengilly sampengilly force-pushed the sampengilly/ior-mapOrAccumulate branch from ab2a495 to 10ec0b9 Compare July 17, 2024 09:57
Add support for mapOrAccumulate functions which accumulate errors
into a "Both" case when run inside an IorRaise scope.
@sampengilly sampengilly force-pushed the sampengilly/ior-mapOrAccumulate branch from 10ec0b9 to af72b38 Compare July 21, 2024 09:26
@sampengilly
Copy link
Contributor Author

Looking at it again. I don't think that zipOrAccumulate makes sense for IorRaise as it's essentially an applicative, the final builder block only makes sense if all of the inputs have succeeded, there doesn't seem to be any room for a partial success that can be represented by an Ior in that case.

@sampengilly
Copy link
Contributor Author

sampengilly commented Sep 10, 2024

Is there any overlap here with #3436? That PR looks like it provides a better general purpose API that is much more DSL like, however I feel like this PR is more focused on the specific case of mapping over iterables and accumulating the errors.

Would the list case (such as parsing a collection of items, dropping failed ones and accumulating errors for them) be satisfied in the DSL approach with something like this?

fun Raise<Error>.parseItem(item: SomeItemType): ParsedType = ...

iorNel {
  val originalList = listOf<SomeItemType>(...)
  val parsedList by accumulating { originalList.map(::parseItem) }
  parsedList
} shouldBe Ior.Both(...)

EDIT: Actually that couldn't work on its own. There'd need to be an additional layer catching the raised error from parseItem and determining what to do with that item in the overall map operation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants