Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions arrow-libs/core/arrow-core/api/arrow-core.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,7 @@ final inline fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?> (arrow.core
final inline fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?> (arrow.core/NonEmptyList<#C>).arrow.core/unzip(kotlin/Function1<#C, kotlin/Pair<#A, #B>>): kotlin/Pair<arrow.core/NonEmptyList<#A>, arrow.core/NonEmptyList<#B>> // arrow.core/unzip|unzip@arrow.core.NonEmptyList<0:2>(kotlin.Function1<0:2,kotlin.Pair<0:0,0:1>>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>}[0]
final inline fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?> (arrow.core/NonEmptySet<#B>).arrow.core/mapOrAccumulate(kotlin/Function2<#A, #A, #A>, kotlin/Function2<arrow.core.raise/RaiseAccumulate<#A>, #B, #C>): arrow.core/Either<#A, arrow.core/NonEmptySet<#C>> // arrow.core/mapOrAccumulate|mapOrAccumulate@arrow.core.NonEmptySet<0:1>(kotlin.Function2<0:0,0:0,0:0>;kotlin.Function2<arrow.core.raise.RaiseAccumulate<0:0>,0:1,0:2>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>}[0]
final inline fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?> (arrow.core/NonEmptySet<#B>).arrow.core/mapOrAccumulate(kotlin/Function2<arrow.core.raise/RaiseAccumulate<#A>, #B, #C>): arrow.core/Either<arrow.core/NonEmptyList<#A>, arrow.core/NonEmptySet<#C>> // arrow.core/mapOrAccumulate|mapOrAccumulate@arrow.core.NonEmptySet<0:1>(kotlin.Function2<arrow.core.raise.RaiseAccumulate<0:0>,0:1,0:2>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>}[0]
final inline fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?> (context(arrow.core.raise/Accumulate<#A>), kotlin.collections/Iterable<#B>).arrow.core.raise.context/mapOrAccumulate(kotlin/Function2<arrow.core.raise/RaiseAccumulate<#A>, #B, #C>): arrow.core.raise/RaiseAccumulate.Value<kotlin.collections/List<#C>> // arrow.core.raise.context/mapOrAccumulate|mapOrAccumulate(arrow.core.raise.Accumulate<0:0>)@kotlin.collections.Iterable<0:1>(kotlin.Function2<arrow.core.raise.RaiseAccumulate<0:0>,0:1,0:2>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>}[0]
final inline fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?> (context(arrow.core.raise/Raise<#A>)).arrow.core.raise.context/withError(kotlin/Function1<#B, #A>, kotlin/Function1<arrow.core.raise/Raise<#B>, #C>): #C // arrow.core.raise.context/withError|withError(arrow.core.raise.Raise<0:0>)(kotlin.Function1<0:1,0:0>;kotlin.Function1<arrow.core.raise.Raise<0:1>,0:2>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>}[0]
final inline fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?> (context(arrow.core.raise/Raise<#A>), kotlin.collections/Iterable<#B>).arrow.core.raise.context/mapOrAccumulate(kotlin/Function2<#A, #A, #A>, kotlin/Function2<arrow.core.raise/RaiseAccumulate<#A>, #B, #C>): kotlin.collections/List<#C> // arrow.core.raise.context/mapOrAccumulate|mapOrAccumulate(arrow.core.raise.Raise<0:0>)@kotlin.collections.Iterable<0:1>(kotlin.Function2<0:0,0:0,0:0>;kotlin.Function2<arrow.core.raise.RaiseAccumulate<0:0>,0:1,0:2>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>}[0]
final inline fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?> (context(arrow.core.raise/Raise<#A>), kotlin.sequences/Sequence<#B>).arrow.core.raise.context/mapOrAccumulate(kotlin/Function2<#A, #A, #A>, kotlin/Function2<arrow.core.raise/RaiseAccumulate<#A>, #B, #C>): kotlin.collections/List<#C> // arrow.core.raise.context/mapOrAccumulate|mapOrAccumulate(arrow.core.raise.Raise<0:0>)@kotlin.sequences.Sequence<0:1>(kotlin.Function2<0:0,0:0,0:0>;kotlin.Function2<arrow.core.raise.RaiseAccumulate<0:0>,0:1,0:2>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>}[0]
Expand Down
1 change: 1 addition & 0 deletions arrow-libs/core/arrow-core/api/jvm/arrow-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,7 @@ public final class arrow/core/raise/Traced : arrow/core/raise/RaiseCancellationE
}

public final class arrow/core/raise/context/RaiseContextualKt {
public static final fun accumulateContextMap (Larrow/core/raise/Accumulate;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Larrow/core/raise/RaiseAccumulate$Value;
public static final fun bind (Larrow/core/raise/Raise;Larrow/core/Either;)Ljava/lang/Object;
public static final fun bind (Larrow/core/raise/Raise;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun bind (Larrow/core/raise/ResultRaise;Ljava/lang/Object;)Ljava/lang/Object;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
@file:OptIn(ExperimentalTypeInference::class, ExperimentalContracts::class)
@file:JvmMultifileClass
@file:JvmName("RaiseContextualKt")
@file:Suppress("LEAKED_IN_PLACE_LAMBDA")

package arrow.core.raise.context

import arrow.core.Either
import arrow.core.EitherNel
import arrow.core.raise.ExperimentalRaiseAccumulateApi
import arrow.core.raise.RaiseAccumulate.Value
import arrow.core.raise.RaiseDSL
import arrow.core.raise.accumulating
import arrow.core.raise.ensureNotNullOrAccumulate
import arrow.core.raise.ensureOrAccumulate
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind.AT_MOST_ONCE
import kotlin.contracts.contract
import kotlin.experimental.ExperimentalTypeInference
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName

public typealias Accumulate<A> = arrow.core.raise.Accumulate<A>

@ExperimentalRaiseAccumulateApi
@JvmName("accumulateContextBindOr")
context(raise: Accumulate<Error>)
public fun <Error, A> Either<Error, A>.bindOrAccumulate(): Value<A> =
with(raise) { this@bindOrAccumulate.bindOrAccumulate() }

@ExperimentalRaiseAccumulateApi
@JvmName("accumulateContextBindAll")
context(raise: Accumulate<Error>)
public fun <Error, A> Iterable<Either<Error, A>>.bindAllOrAccumulate(): Value<List<A>> =
with(raise) { this@bindAllOrAccumulate.bindAllOrAccumulate() }

@ExperimentalRaiseAccumulateApi
@JvmName("accumulateContextBindNel")
context(raise: Accumulate<Error>)
public fun <Error, A> EitherNel<Error, A>.bindNelOrAccumulate(): Value<A> =
with(raise) { this@bindNelOrAccumulate.bindNelOrAccumulate() }

@ExperimentalRaiseAccumulateApi
@RaiseDSL
@IgnorableReturnValue
@JvmName("accumulateContextEnsure")
context(raise: Accumulate<Error>)
public inline fun <Error> ensureOrAccumulate(condition: Boolean, error: () -> Error): Value<Unit> {
contract { callsInPlace(error, AT_MOST_ONCE) }
return raise.ensureOrAccumulate(condition, error)
}

@ExperimentalRaiseAccumulateApi
@RaiseDSL
@JvmName("accumulateContextEnsureNotNull")
context(raise: Accumulate<Error>)
public inline fun <Error, B : Any> ensureNotNullOrAccumulate(value: B?, error: () -> Error): Value<B> {
contract { callsInPlace(error, AT_MOST_ONCE) }
return raise.ensureNotNullOrAccumulate(value, error)
}

@ExperimentalRaiseAccumulateApi
@JvmName("accumulateContextGet")
context(raise: Accumulate<Error>)
public fun <Error, A> Either<Error, A>.getOrAccumulate(recover: (Error) -> A): A =
with(raise) { this@getOrAccumulate.getOrAccumulate(recover) }

@ExperimentalRaiseAccumulateApi
@JvmName("accumulateContextAccumulating")
context(raise: Accumulate<Error>)
public inline fun <Error, A> accumulating(block: context(RaiseAccumulate<Error>) () -> A): Value<A> {
contract { callsInPlace(block, AT_MOST_ONCE) }
return raise.accumulating { block() }
}

@JvmName("accumulateContextMap")
context(raise: Accumulate<Error>)
@RaiseDSL
public inline fun <Error, A, B> Iterable<A>.mapOrAccumulate(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this one. It has a different return type from the RaiseAccumulate overload.
There's definitely a use for it, just unsure about the name.

Accumulate is basically a delayed Raise (which lets it accumulate errors), so the convention usually is that XOrAccumulate methods return Value. mapOrAccumulate predates that conventino. It's ought to be called mapAccumulating like forEachAccumulating, but that's an annoying name change to go through.
(Maybe the opposite convention could work? and then forEachAccumulating is just the odd one out? All Value-returning functions are still experimental, so we could change them...)

mapOrAccumulate is a good name for this operation, but it means someone using RaiseAccumulate vs just Accumulate gets very different behavior. I suggest we leave it to another PR maybe?

transform: context(RaiseAccumulate<Error>) (A) -> B
): Value<List<B>> = raise.accumulating {
this@mapOrAccumulate.mapOrAccumulate(transform)
}
Loading