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

Allow to recover to Option<A> in Option.catch #2437

Merged
merged 3 commits into from
Jul 19, 2021
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,11 @@ public sealed class Option<out A> {
public operator fun <A> invoke(a: A): Option<A> = Some(a)

@JvmStatic
@JvmName("tryCatch")
@JvmName("tryCatchOrSideEffect")
@Deprecated(
"Side-effecting recover which loses Throwable is no longer supported",
ReplaceWith("Option.catch({ recover(it); None }, f)")
)
public inline fun <A> catch(recover: (Throwable) -> Unit, f: () -> A): Option<A> =
try {
Some(f())
Expand All @@ -347,6 +351,25 @@ public sealed class Option<out A> {
None
}

@JvmStatic
@JvmName("tryCatchOrNone")
/**
* Ignores exceptions and returns None if one is thrown
*/
public inline fun <A> catch(f: () -> A): Option<A> {
val recover: (Throwable) -> Option<A> = { None }
return catch(recover, f)
}

@JvmStatic
@JvmName("tryCatch")
public inline fun <A> catch(recover: (Throwable) -> Option<A>, f: () -> A): Option<A> =
try {
Some(f())
} catch (t: Throwable) {
recover(t.nonFatalOrThrow())
}

@JvmStatic
public fun <A, B> lift(f: (A) -> B): (Option<A>) -> Option<B> =
{ it.map(f) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,27 @@ class OptionTest : UnitSpec() {
option.map { it.valid() }.sequenceValidated() shouldBe option.traverseValidated { it.valid() }
}
}

"catch should return Some(result) when f does not throw" {
val recover: (Throwable) -> Option<Int> = { _ -> None}
Option.catch(recover) { 1 } shouldBe Some(1)
}

"catch should return Some(recoverValue) when f throws" {
val exception = Exception("Boom!")
val recoverValue = 10
val recover: (Throwable) -> Option<Int> = { _ -> Some(recoverValue) }
Option.catch(recover) { throw exception } shouldBe Some(recoverValue)
}

"catch should return Some(result) when f does not throw" {
Option.catch { 1 } shouldBe Some(1)
}

"catch should return None when f throws" {
val exception = Exception("Boom!")
Option.catch { throw exception } shouldBe None
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package arrow.core;

import kotlin.Unit;
import kotlin.jvm.functions.Function1;

public class OptionUsage {
Expand All @@ -9,7 +8,7 @@ public void testUsage() {
Option<Integer> fromNullable = Option.fromNullable(null);
Option.tryCatch((throwable) -> {
throwable.printStackTrace();
return Unit.INSTANCE;
return None.INSTANCE;
}, () -> 1);

Option<Integer> invoke = Option.invoke(1);
Expand Down