Skip to content

Commit

Permalink
ignoreErrors for Raise (#3100)
Browse files Browse the repository at this point in the history
Co-authored-by: Simon Vergauwen <[email protected]>
  • Loading branch information
serras and nomisRev authored Jul 19, 2023
1 parent 90587dd commit 40bd0f4
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
26 changes: 26 additions & 0 deletions arrow-libs/core/arrow-core/api/arrow-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -3333,6 +3333,30 @@ public final class arrow/core/raise/DefaultRaise : arrow/core/raise/Raise {
public abstract interface annotation class arrow/core/raise/ExperimentalTraceApi : java/lang/annotation/Annotation {
}

public final class arrow/core/raise/IgnoreErrorsRaise : arrow/core/raise/Raise {
public fun <init> (Larrow/core/raise/Raise;Lkotlin/jvm/functions/Function0;)V
public fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun bind (Larrow/core/Either;)Ljava/lang/Object;
public final fun bind (Larrow/core/Option;)Ljava/lang/Object;
public fun bind (Larrow/core/Validated;)Ljava/lang/Object;
public fun bind (Larrow/core/continuations/EagerEffect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun bind (Larrow/core/continuations/Effect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun bind (Ljava/lang/Object;)Ljava/lang/Object;
public fun bind (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public fun bind (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun bindAll (Larrow/core/NonEmptyList;)Larrow/core/NonEmptyList;
public fun bindAll (Ljava/lang/Iterable;)Ljava/util/List;
public fun bindAll (Ljava/util/Map;)Ljava/util/Map;
public fun bindAll-1TN0_VU (Ljava/util/Set;)Ljava/util/Set;
public fun catch (Larrow/core/continuations/Effect;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun ensure (Z)V
public final fun ensureNotNull (Ljava/lang/Object;)Ljava/lang/Object;
public fun invoke (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public fun invoke (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun raise (Ljava/lang/Object;)Ljava/lang/Void;
public fun shift (Ljava/lang/Object;)Ljava/lang/Object;
}

public final class arrow/core/raise/IorRaise : arrow/core/raise/Raise {
public fun <init> (Lkotlin/jvm/functions/Function2;Ljava/util/concurrent/atomic/AtomicReference;Larrow/core/raise/Raise;)V
public fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
Expand Down Expand Up @@ -3381,6 +3405,7 @@ public final class arrow/core/raise/NullableRaise : arrow/core/raise/Raise {
public fun catch (Larrow/core/continuations/Effect;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun ensure (Z)V
public final fun ensureNotNull (Ljava/lang/Object;)Ljava/lang/Object;
public final fun ignoreErrors (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public fun invoke (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public fun invoke (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public synthetic fun raise (Ljava/lang/Object;)Ljava/lang/Void;
Expand Down Expand Up @@ -3411,6 +3436,7 @@ public final class arrow/core/raise/OptionRaise : arrow/core/raise/Raise {
public fun catch (Larrow/core/continuations/Effect;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun ensure (Z)V
public final fun ensureNotNull (Ljava/lang/Object;)Ljava/lang/Object;
public final fun ignoreErrors (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public fun invoke (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public fun invoke (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun raise (Larrow/core/None;)Ljava/lang/Void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,37 @@ public inline fun <Error, A> ior(noinline combineError: (Error, Error) -> Error,
)
}

/**
* Implementation of [Raise] used by `ignoreErrors`.
* You should never use this directly.
*/
public class IgnoreErrorsRaise<N>(
private val raise: Raise<N>,
private val error: () -> N
) : Raise<Any?> {
@RaiseDSL
override fun raise(r: Any?): Nothing =
raise.raise(error())

@RaiseDSL
public fun ensure(value: Boolean): Unit = ensure(value) { null }

@RaiseDSL
public fun <A> Option<A>.bind(): A = getOrElse { raise(null) }

@RaiseDSL
public fun <A> A?.bind(): A {
contract { returns() implies (this@bind != null) }
return this ?: raise(null)
}

@RaiseDSL
public fun <A> ensureNotNull(value: A?): A {
contract { returns() implies (value != null) }
return ensureNotNull(value) { null }
}
}

public typealias Null = Nothing?

/**
Expand Down Expand Up @@ -136,6 +167,15 @@ public class NullableRaise(private val raise: Raise<Null>) : Raise<Null> by rais
null -> recover()
else -> nullable
}

/**
* Introduces a scope where you can [bind] errors of any type,
* but no information is saved in the [raise] case.
*/
@RaiseDSL
public inline fun <A> ignoreErrors(
@BuilderInference block: IgnoreErrorsRaise<Null>.() -> A,
): A = block(IgnoreErrorsRaise(this) { null })
}

/**
Expand Down Expand Up @@ -219,6 +259,15 @@ public class OptionRaise(private val raise: Raise<None>) : Raise<None> by raise
is None -> recover()
is Some<A> -> option.value
}

/**
* Introduces a scope where you can [bind] errors of any type,
* but no information is saved in the [raise] case.
*/
@RaiseDSL
public inline fun <A> ignoreErrors(
@BuilderInference block: IgnoreErrorsRaise<None>.() -> A,
): A = block(IgnoreErrorsRaise(this) { None })
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ class NullableSpec : StringSpec({
} shouldBe "1"
}

"binding either in nullable" {
nullable {
val number = Either.Right("s".length)
val string = number.map(Int::toString).bind()
string
} shouldBe "1"
}

"binding either in nullable, ignore errors" {
nullable {
val number = Either.Right("s".length) as Either<Boolean, Int>
val string = ignoreErrors { number.map(Int::toString).bind() }
string
} shouldBe "1"
}

"short circuit option" {
nullable<Int> {
val number = Some("s".length)
Expand Down

0 comments on commit 40bd0f4

Please sign in to comment.