diff --git a/modules/core/arrow-core/src/main/kotlin/arrow/core/Either.kt b/modules/core/arrow-core/src/main/kotlin/arrow/core/Either.kt index 3a45d77fdff..a0453a8c125 100644 --- a/modules/core/arrow-core/src/main/kotlin/arrow/core/Either.kt +++ b/modules/core/arrow-core/src/main/kotlin/arrow/core/Either.kt @@ -46,7 +46,7 @@ sealed class Either : EitherOf { * @param ifRight the function to apply if this is a [Right] * @return the results of applying the function */ - inline fun fold(crossinline ifLeft: (A) -> C, crossinline ifRight: (B) -> C): C = when (this) { + inline fun fold(ifLeft: (A) -> C, ifRight: (B) -> C): C = when (this) { is Right -> ifRight(b) is Left -> ifLeft(a) } @@ -58,7 +58,7 @@ sealed class Either : EitherOf { } fun foldLeft(initial: C, rightOperation: (C, B) -> C): C = - this.fix().let { either -> + fix().let { either -> when (either) { is Right -> rightOperation(initial, either.b) is Left -> initial @@ -66,7 +66,7 @@ sealed class Either : EitherOf { } fun foldRight(initial: Eval, rightOperation: (B, Eval) -> Eval): Eval = - this.fix().let { either -> + fix().let { either -> when (either) { is Right -> rightOperation(either.b, initial) is Left -> initial @@ -94,11 +94,8 @@ sealed class Either : EitherOf { * ``` */ @Suppress("UNCHECKED_CAST") - inline fun map(crossinline f: (B) -> C): Either = - when (this) { - is Right -> Right(f(b)) - is Left -> this - } + inline fun map(f: (B) -> C): Either = + flatMap { Right(f(it)) } /** * The given function is applied if this is a `Left`. @@ -109,13 +106,13 @@ sealed class Either : EitherOf { * Left(12).mapLeft { "flower" } // Result: Left("flower) * ``` */ - inline fun mapLeft(crossinline f: (A) -> C): Either = + inline fun mapLeft(f: (A) -> C): Either = fold({ Left(f(it)) }, { Right(it) }) /** * Map over Left and Right of this Either */ - inline fun bimap(crossinline leftOperation: (A) -> C, crossinline rightOperation: (B) -> D): Either = + inline fun bimap(leftOperation: (A) -> C, rightOperation: (B) -> D): Either = fold({ Left(leftOperation(it)) }, { Right(rightOperation(it)) }) /** @@ -131,7 +128,7 @@ sealed class Either : EitherOf { * left.exists { it > 10 } // Result: false * ``` */ - inline fun exists(crossinline predicate: (B) -> Boolean): Boolean = + fun exists(predicate: (B) -> Boolean): Boolean = fold({ false }, { predicate(it) }) /** @@ -211,8 +208,7 @@ fun Right(right: R): Either = Either.right(right) * * @param f The function to bind across [Either.Right]. */ -@Suppress("UNCHECKED_CAST") -fun EitherOf.flatMap(f: (B) -> Either): Either = +inline fun EitherOf.flatMap(f: (B) -> Either): Either = fix().let { when (it) { is Right -> f(it.b) @@ -229,7 +225,7 @@ fun EitherOf.flatMap(f: (B) -> Either): Either = * Left(12).getOrElse(17) // Result: 17 * ``` */ -inline fun EitherOf<*, B>.getOrElse(crossinline default: () -> B): B = +inline fun EitherOf<*, B>.getOrElse(default: () -> B): B = fix().fold({ default() }, ::identity) /** @@ -242,7 +238,7 @@ inline fun EitherOf<*, B>.getOrElse(crossinline default: () -> B): B = * ``` */ inline fun EitherOf<*, B>.orNull(): B? = - getOrElse { null } + getOrElse { null } /** * Returns the value from this [Either.Right] or allows clients to transform [Either.Left] to [Either.Right] while providing access to @@ -254,7 +250,7 @@ inline fun EitherOf<*, B>.orNull(): B? = * Left(12).getOrHandle { it + 5 } // Result: 17 * ``` */ -inline fun EitherOf.getOrHandle(crossinline default: (A) -> B): B = +inline fun EitherOf.getOrHandle(default: (A) -> B): B = fix().fold({ default(it) }, ::identity) /** @@ -273,8 +269,8 @@ inline fun EitherOf.getOrHandle(crossinline default: (A) -> B): B = * left.filterOrElse({ it > 10 }, { -1 }) // Result: Left(12) * ``` */ -inline fun EitherOf.filterOrElse(crossinline predicate: (B) -> Boolean, crossinline default: () -> A): Either = - fix().fold({ Left(it) }, { if (predicate(it)) Right(it) else Left(default()) }) +inline fun EitherOf.filterOrElse(predicate: (B) -> Boolean, default: () -> A): Either = + flatMap { if (predicate(it)) Right(it) else Left(default()) } /** * * Returns [Either.Right] with the existing value of [Either.Right] if this is an [Either.Right] with a non-null value. @@ -316,7 +312,7 @@ fun EitherOf.ap(ff: EitherOf C>): Either = fun EitherOf.combineK(y: EitherOf): Either = when (this) { is Either.Left -> y.fix() - else -> this.fix() + else -> fix() } @Deprecated(DeprecatedAmbiguity, ReplaceWith("Try { body }.toEither()")) diff --git a/modules/core/arrow-core/src/main/kotlin/arrow/core/Id.kt b/modules/core/arrow-core/src/main/kotlin/arrow/core/Id.kt index 1064f2e26ec..05ccc4567ca 100644 --- a/modules/core/arrow-core/src/main/kotlin/arrow/core/Id.kt +++ b/modules/core/arrow-core/src/main/kotlin/arrow/core/Id.kt @@ -15,7 +15,7 @@ data class Id(val value: A) : IdOf { fun foldRight(initial: Eval, operation: (A, Eval) -> Eval): Eval = operation(this.fix().value, initial) - fun coflatMap(f: (IdOf) -> B): Id = this.fix().map({ f(this) }) + fun coflatMap(f: (IdOf) -> B): Id = this.fix().map { f(this) } fun extract(): A = this.fix().value diff --git a/modules/core/arrow-core/src/main/kotlin/arrow/core/Option.kt b/modules/core/arrow-core/src/main/kotlin/arrow/core/Option.kt index 9deb343df92..c7fd7871277 100644 --- a/modules/core/arrow-core/src/main/kotlin/arrow/core/Option.kt +++ b/modules/core/arrow-core/src/main/kotlin/arrow/core/Option.kt @@ -66,13 +66,8 @@ sealed class Option : OptionOf { * @param f the function to apply * @see flatMap */ - inline fun map(crossinline f: (A) -> B): Option = fold({ None }, { a -> Some(f(a)) }) - - inline fun map(p1: Option, crossinline f: (A, P1) -> R): Option = if (isEmpty()) { - None - } else { - p1.map { pp1 -> f(get(), pp1) } - } + inline fun map(f: (A) -> B): Option = + flatMap { a -> Some(f(a)) } inline fun fold(ifEmpty: () -> R, ifSome: (A) -> R): R = when (this) { is None -> ifEmpty() @@ -89,9 +84,14 @@ sealed class Option : OptionOf { * @param f the function to apply * @see map */ - fun flatMap(f: (A) -> OptionOf): Option = fold({ None }, { a -> f(a) }).fix() + inline fun flatMap(f: (A) -> OptionOf): Option = + when (this) { + is None -> this + is Some -> f(t).fix() + } - fun ap(ff: OptionOf<(A) -> B>): Option = ff.fix().flatMap { this.fix().map(it) } + fun ap(ff: OptionOf<(A) -> B>): Option = + ff.fix().flatMap { this.fix().map(it) } /** * Returns this $option if it is nonempty '''and''' applying the predicate $p to @@ -99,8 +99,8 @@ sealed class Option : OptionOf { * * @param predicate the predicate used for testing. */ - inline fun filter(crossinline predicate: Predicate): Option = - fold({ None }, { a -> if (predicate(a)) Some(a) else None }) + fun filter(predicate: Predicate): Option = + flatMap { a -> if (predicate(a)) Some(a) else None } /** * Returns this $option if it is nonempty '''and''' applying the predicate $p to @@ -108,7 +108,8 @@ sealed class Option : OptionOf { * * @param predicate the predicate used for testing. */ - inline fun filterNot(crossinline predicate: Predicate): Option = fold({ None }, { a -> if (!predicate(a)) Some(a) else None }) + fun filterNot(predicate: Predicate): Option = + flatMap { a -> if (!predicate(a)) Some(a) else None } /** * Returns true if this option is nonempty '''and''' the predicate @@ -117,7 +118,7 @@ sealed class Option : OptionOf { * * @param predicate the predicate to test */ - inline fun exists(crossinline predicate: Predicate): Boolean = fold({ false }, { a -> predicate(a) }) + fun exists(predicate: Predicate): Boolean = fold({ false }, { a -> predicate(a) }) /** * Returns true if this option is empty '''or''' the predicate @@ -125,7 +126,7 @@ sealed class Option : OptionOf { * * @param p the predicate to test */ - inline fun forall(crossinline p: Predicate): Boolean = fold({ true }, p) + fun forall(p: Predicate): Boolean = fold({ true }, p) @Deprecated(DeprecatedUnsafeAccess, ReplaceWith("fold({ Unit }, f)")) inline fun forEach(f: (A) -> Unit) { @@ -133,7 +134,7 @@ sealed class Option : OptionOf { } fun foldLeft(initial: B, operation: (B, A) -> B): B = - this.fix().let { option -> + fix().let { option -> when (option) { is Some -> operation(initial, option.t) is None -> initial @@ -141,7 +142,7 @@ sealed class Option : OptionOf { } fun foldRight(initial: Eval, operation: (A, Eval) -> Eval): Eval = - this.fix().let { option -> + fix().let { option -> when (option) { is Some -> operation(option.t, initial) is None -> initial @@ -151,7 +152,7 @@ sealed class Option : OptionOf { fun toEither(ifEmpty: () -> L): Either = fold({ ifEmpty().left() }, { it.right() }) - fun toList(): List = fold(::emptyList, { listOf(it) }) + fun toList(): List = fold(::emptyList) { listOf(it) } infix fun and(value: Option): Option = if (isEmpty()) { None @@ -190,7 +191,7 @@ fun Option.getOrElse(default: () -> T): T = fold({ default() }, ::identit * * @param alternative the default option if this is empty. */ -fun OptionOf.orElse(alternative: () -> Option): Option = if (fix().isEmpty()) alternative() else fix() +inline fun OptionOf.orElse(alternative: () -> Option): Option = if (fix().isEmpty()) alternative() else fix() infix fun OptionOf.or(value: Option): Option = if (fix().isEmpty()) { value diff --git a/modules/core/arrow-core/src/main/kotlin/arrow/core/Try.kt b/modules/core/arrow-core/src/main/kotlin/arrow/core/Try.kt index 3ffaeaa9cb2..3eb9276e43f 100644 --- a/modules/core/arrow-core/src/main/kotlin/arrow/core/Try.kt +++ b/modules/core/arrow-core/src/main/kotlin/arrow/core/Try.kt @@ -2,7 +2,7 @@ package arrow.core import arrow.higherkind -typealias Failure = Try.Failure +typealias Failure = Try.Failure typealias Success = Try.Success /** @@ -21,7 +21,7 @@ sealed class Try : TryOf { tailrec fun tailRecM(a: A, f: (A) -> TryOf>): Try { val ev: Try> = f(a).fix() return when (ev) { - is Failure -> Failure(ev.exception).fix() + is Failure -> Failure(ev.exception).fix() is Success -> { val b: Either = ev.value when (b) { @@ -52,21 +52,23 @@ sealed class Try : TryOf { /** * Returns the given function applied to the value from this `Success` or returns this if this is a `Failure`. */ - inline fun flatMap(crossinline f: (A) -> TryOf): Try = fold({ raise(it) }, { f(it).fix() }) + inline fun flatMap(f: (A) -> TryOf): Try = + when (this) { + is Failure -> this + is Success -> f(value).fix() + } /** * Maps the given function to the value from this `Success` or returns this if this is a `Failure`. */ - inline fun map(crossinline f: (A) -> B): Try = fold({ Failure(it) }, { Success(f(it)) }) + inline fun map(f: (A) -> B): Try = + flatMap { Success(f(it)) } /** * Converts this to a `Failure` if the predicate is not satisfied. */ - inline fun filter(crossinline p: Predicate): Try = - fold( - { Failure(it) }, - { if (p(it)) Success(it) else Failure(TryException.PredicateException("Predicate does not hold for $it")) } - ) + fun filter(p: Predicate): Try = + flatMap { if (p(it)) Success(it) else Failure(TryException.PredicateException("Predicate does not hold for $it")) } /** * Inverts this `Try`. If this is a `Failure`, returns its exception wrapped in a `Success`. @@ -126,19 +128,19 @@ sealed class Try : TryOf { fun toEither(): Either = fold({ Left(it) }, { Right(it) }) - fun foldLeft(initial: B, operation: (B, A) -> B): B = this.fix().fold({ initial }, { operation(initial, it) }) + fun foldLeft(initial: B, operation: (B, A) -> B): B = fix().fold({ initial }, { operation(initial, it) }) - fun foldRight(initial: Eval, operation: (A, Eval) -> Eval): Eval = this.fix().fold({ initial }, { operation(it, initial) }) + fun foldRight(initial: Eval, operation: (A, Eval) -> Eval): Eval = fix().fold({ initial }, { operation(it, initial) }) /** * The `Failure` type represents a computation that result in an exception. */ - data class Failure(val exception: Throwable) : Try() { + data class Failure(val exception: Throwable) : Try() { override fun isFailure(): Boolean = true override fun isSuccess(): Boolean = false - override fun get(): A { + override fun get(): Nothing { throw exception } } @@ -155,7 +157,7 @@ sealed class Try : TryOf { } } -sealed class TryException(override val message: String) : kotlin.Exception(message) { +sealed class TryException(override val message: String) : Exception(message) { data class PredicateException(override val message: String) : TryException(message) data class UnsupportedOperationException(override val message: String) : TryException(message) } @@ -165,22 +167,22 @@ sealed class TryException(override val message: String) : kotlin.Exception(messa * * ''Note:'': This will throw an exception if it is not a success and default throws an exception. */ -fun TryOf.getOrDefault(default: () -> B): B = fix().fold({ default() }, ::identity) +inline fun TryOf.getOrDefault(default: () -> B): B = fix().fold({ default() }, ::identity) /** * Returns the value from this `Success` or the given `default` argument if this is a `Failure`. * * ''Note:'': This will throw an exception if it is not a success and default throws an exception. */ -fun TryOf.getOrElse(default: (Throwable) -> B): B = fix().fold(default, ::identity) +inline fun TryOf.getOrElse(default: (Throwable) -> B): B = fix().fold(default, ::identity) /** * Returns the value from this `Success` or null if this is a `Failure`. */ fun TryOf.orNull(): B? = getOrElse { null } -fun TryOf.orElse(f: () -> TryOf): Try = when (this.fix()) { - is Try.Success -> this.fix() +inline fun TryOf.orElse(f: () -> TryOf): Try = when (fix()) { + is Try.Success -> fix() is Try.Failure -> f().fix() } @@ -206,8 +208,9 @@ fun TryOf.handle(f: (Throwable) -> A): Try = fix().recover(f) * Completes this `Try` by applying the function `ifFailure` to this if this is of type `Failure`, * or conversely, by applying `ifSuccess` if this is a `Success`. */ -fun TryOf.transform(ifSuccess: (A) -> TryOf, ifFailure: (Throwable) -> TryOf): Try = fix().fold({ ifFailure(it).fix() }, { fix().flatMap(ifSuccess) }) +@Deprecated(DeprecatedAmbiguity, ReplaceWith("fold(ifFailure, ifSuccess)")) +inline fun TryOf.transform(ifSuccess: (A) -> TryOf, ifFailure: (Throwable) -> TryOf): Try = fix().fold({ ifFailure(it).fix() }, { fix().flatMap(ifSuccess) }) fun (() -> A).try_(): Try = Try(this) -fun TryOf>.flatten(): Try = fix().flatMap(::identity) \ No newline at end of file +fun TryOf>.flatten(): Try = fix().flatMap(::identity) diff --git a/modules/core/arrow-core/src/main/kotlin/arrow/core/utils.kt b/modules/core/arrow-core/src/main/kotlin/arrow/core/utils.kt index 30034bae294..d50577aa02b 100644 --- a/modules/core/arrow-core/src/main/kotlin/arrow/core/utils.kt +++ b/modules/core/arrow-core/src/main/kotlin/arrow/core/utils.kt @@ -35,4 +35,4 @@ class GetterSetterOperation(override val getter: (K) -> V, override val SetterOperation const val DeprecatedUnsafeAccess: String = "This function is unsafe and will be removed in future versions of Arrow. Replace or import `arrow.syntax.unsafe.*` if you wish to continue using it in this way" -const val DeprecatedAmbiguity: String = "This function is ambiguous and will be removed in future versions of Arrow" \ No newline at end of file +const val DeprecatedAmbiguity: String = "This function is ambiguous and will be removed in future versions of Arrow" diff --git a/modules/core/arrow-data/src/test/kotlin/arrow/data/OptionTest.kt b/modules/core/arrow-data/src/test/kotlin/arrow/data/OptionTest.kt index 0944302cc5b..6e240942f08 100755 --- a/modules/core/arrow-data/src/test/kotlin/arrow/data/OptionTest.kt +++ b/modules/core/arrow-data/src/test/kotlin/arrow/data/OptionTest.kt @@ -97,9 +97,6 @@ class OptionTest : UnitSpec() { "map" { some.map(String::toUpperCase).get() shouldBe "KOTLIN" none.map(String::toUpperCase) shouldBe None - - some.map(Some(12)) { name, version -> "${name.toUpperCase()} M$version" }.get() shouldBe "KOTLIN M12" - none.map(Some(12)) { name, version -> "${name.toUpperCase()} M$version" } shouldBe None } "fold" { diff --git a/modules/core/arrow-data/src/test/kotlin/arrow/data/TryTest.kt b/modules/core/arrow-data/src/test/kotlin/arrow/data/TryTest.kt index 5f1971ffd25..73563862f0f 100644 --- a/modules/core/arrow-data/src/test/kotlin/arrow/data/TryTest.kt +++ b/modules/core/arrow-data/src/test/kotlin/arrow/data/TryTest.kt @@ -2,8 +2,6 @@ package arrow.data import arrow.core.* import arrow.instances.* -import arrow.instances.eq -import arrow.instances.extensions import arrow.test.UnitSpec import arrow.test.laws.* import arrow.typeclasses.Eq @@ -66,14 +64,14 @@ class TryTest : UnitSpec() { "invoke of exception should be failure" { val ex = Exception() - Try.invoke { throw ex } shouldBe Failure(ex) + Try.invoke { throw ex } shouldBe Failure(ex) } "filter evaluates predicate" { val failure: Try = Failure(Exception()) Success(1).filter { true } shouldBe Success(1) - Success(1).filter { false } shouldBe Failure(TryException.PredicateException("Predicate does not hold for 1")) + Success(1).filter { false } shouldBe Failure(TryException.PredicateException("Predicate does not hold for 1")) failure.filter { true } shouldBe failure failure.filter { false } shouldBe failure } @@ -82,12 +80,12 @@ class TryTest : UnitSpec() { val ex = Exception() val failure: Try = Failure(ex) - Success(1).failed() shouldBe Failure(TryException.UnsupportedOperationException("Success")) + Success(1).failed() shouldBe Failure(TryException.UnsupportedOperationException("Success")) failure.failed() shouldBe Success(ex) } "fold should call left function on Failure" { - Failure(Exception()).fold({ 2 }, { 3 }) shouldBe 2 + Failure(Exception()).fold({ 2 }, { 3 }) shouldBe 2 } "fold should call right function on Success" { @@ -106,32 +104,33 @@ class TryTest : UnitSpec() { "getOrDefault returns default if Failure" { Success(1).getOrDefault { 2 } shouldBe 1 - Failure(Exception()).getOrDefault { 2 } shouldBe 2 + Failure(Exception()).getOrDefault { 2 } shouldBe 2 } "getOrElse returns default if Failure" { val e: Throwable = Exception() Success(1).getOrElse { _: Throwable -> 2 } shouldBe 1 - Failure(e).getOrElse { (it shouldEqual e); 2 } shouldBe 2 + Failure(e).getOrElse { (it shouldEqual e); 2 } shouldBe 2 } "orNull returns null if Failure" { - val e: Throwable = Exception() - Success(1).orNull() shouldBe 1 - Failure(e).orNull() shouldBe null + + val e: Throwable = Exception() + val failure1: Try = Failure(e) + failure1.orNull() shouldBe null } "recoverWith should modify Failure entity" { - Success(1).recoverWith { Failure(Exception()) } shouldBe Success(1) + Success(1).recoverWith { Failure(Exception()) } shouldBe Success(1) Success(1).recoverWith { Success(2) } shouldBe Success(1) - Failure(Exception()).recoverWith { Success(2) } shouldBe Success(2) + Failure(Exception()).recoverWith { Success(2) } shouldBe Success(2) } "recover should modify Failure value" { Success(1).recover { 2 } shouldBe Success(1) - Failure(Exception()).recover { 2 } shouldBe Success(2) + Failure(Exception()).recover { 2 } shouldBe Success(2) } "transform applies left function for Success" { @@ -139,7 +138,7 @@ class TryTest : UnitSpec() { } "transform applies right function for Failure" { - Failure(Exception()).transform({ Success(2) }, { Success(3) }) shouldBe Success(3) + Failure(Exception()).transform({ Success(2) }, { Success(3) }) shouldBe Success(3) } "Cartesian builder should build products over homogeneous Try" { @@ -157,8 +156,8 @@ class TryTest : UnitSpec() { map( Success(13), Success("Doctor"), - Success(false), - { (a, b, c) -> "${a}th $b is $c" }) shouldBe Success("13th Doctor is false") + Success(false) + ) { (a, b, c) -> "${a}th $b is $c" } shouldBe Success("13th Doctor is false") } } @@ -168,9 +167,9 @@ class TryTest : UnitSpec() { ForTry extensions { map( Success(13), - Failure(DoctorNotFoundException("13th Doctor is coming!")), - Success("Who"), - { (a, b, c) -> "${a}th $b is $c" }) shouldBe Failure(DoctorNotFoundException("13th Doctor is coming!")) + Failure(DoctorNotFoundException("13th Doctor is coming!")), + Success("Who") + ) { (a, b, c) -> "${a}th $b is $c" } shouldBe Failure(DoctorNotFoundException("13th Doctor is coming!")) } } diff --git a/modules/core/arrow-instances-core/src/main/kotlin/arrow/instances/try.kt b/modules/core/arrow-instances-core/src/main/kotlin/arrow/instances/try.kt index a83024f4f5f..41282535291 100644 --- a/modules/core/arrow-instances-core/src/main/kotlin/arrow/instances/try.kt +++ b/modules/core/arrow-instances-core/src/main/kotlin/arrow/instances/try.kt @@ -1,28 +1,10 @@ package arrow.instances import arrow.Kind -import arrow.core.Either -import arrow.core.Eval -import arrow.core.Failure -import arrow.core.ForTry -import arrow.core.Success -import arrow.core.Try -import arrow.core.TryOf -import arrow.core.fix -import arrow.core.identity -import arrow.core.recoverWith +import arrow.core.* +import arrow.core.Try.Failure import arrow.instance -import arrow.typeclasses.Applicative -import arrow.typeclasses.ApplicativeError -import arrow.typeclasses.Eq -import arrow.typeclasses.Foldable -import arrow.typeclasses.Functor -import arrow.typeclasses.Monad -import arrow.typeclasses.MonadError -import arrow.typeclasses.Monoid -import arrow.typeclasses.Semigroup -import arrow.typeclasses.Show -import arrow.typeclasses.Traverse +import arrow.typeclasses.* import arrow.instances.traverse as tryTraverse fun Try.combine(SG: Semigroup, b: Try): Try = diff --git a/modules/core/arrow-syntax/src/main/kotlin/arrow/syntax/collections/list.kt b/modules/core/arrow-syntax/src/main/kotlin/arrow/syntax/collections/list.kt index eef76e2dc56..a23792fec7d 100644 --- a/modules/core/arrow-syntax/src/main/kotlin/arrow/syntax/collections/list.kt +++ b/modules/core/arrow-syntax/src/main/kotlin/arrow/syntax/collections/list.kt @@ -1,8 +1,6 @@ package arrow.syntax.collections import arrow.core.Option -import arrow.core.Some -import arrow.core.identity import arrow.core.toOption /** @@ -14,15 +12,6 @@ infix fun T.prependTo(list: List): List = listOf(this) + list fun List.destructured(): Pair> = first() to tail() -fun List.optionTraverse(f: (T) -> Option): Option> = foldRight(Some(emptyList())) { i: T, accumulator: Option> -> - f(i).map(accumulator) { head: R, tail: List -> - head prependTo tail - } -} - -fun List>.optionSequential(): Option> = optionTraverse(::identity) - fun List.firstOption(): Option = firstOrNull().toOption() fun List>.flatten(): List = filter { it.isDefined() }.map { it.get() } - diff --git a/modules/core/arrow-test/src/main/kotlin/arrow/test/generators/Generators.kt b/modules/core/arrow-test/src/main/kotlin/arrow/test/generators/Generators.kt index f5882b94636..39258f01edc 100644 --- a/modules/core/arrow-test/src/main/kotlin/arrow/test/generators/Generators.kt +++ b/modules/core/arrow-test/src/main/kotlin/arrow/test/generators/Generators.kt @@ -135,7 +135,7 @@ inline fun genValidated(genE: Gen, genA: Gen): Gen< inline fun genTry(genA: Gen, genThrowable: Gen = genThrowable()): Gen> = Gen.create { genEither(genThrowable, genA).generate().fold( - { throwable -> Failure(throwable) }, + { throwable -> Failure(throwable) }, { a -> Success(a) } ) } diff --git a/modules/docs/arrow-docs/docs/docs/datatypes/option/README.md b/modules/docs/arrow-docs/docs/docs/datatypes/option/README.md index 9509e02c15b..0ed42b2ee06 100644 --- a/modules/docs/arrow-docs/docs/docs/datatypes/option/README.md +++ b/modules/docs/arrow-docs/docs/docs/datatypes/option/README.md @@ -141,7 +141,7 @@ Transforming the inner contents import arrow.typeclasses.* import arrow.instances.* -ForOption extensions { +Option.functor().run { Some(1).map { it + 1 } } ``` diff --git a/modules/docs/arrow-docs/docs/docs/datatypes/try/README.md b/modules/docs/arrow-docs/docs/docs/datatypes/try/README.md index e2bb647d9e6..7135daf2095 100644 --- a/modules/docs/arrow-docs/docs/docs/datatypes/try/README.md +++ b/modules/docs/arrow-docs/docs/docs/datatypes/try/README.md @@ -16,7 +16,7 @@ For example, we have `Option` to model the absence of a value, or `Either` to mo On the other hand, we have `Try`, which represents a computation that can result in an `A` result (as long as the computation is successful) or in an exception if something has gone wrong. -That is, there are only two possible implementations of `Try`: a `Try` instance where the operation has been successful, which is represented as `Success`; or a `Try` instance where the computation has failed with a `Throwable`, which is represented as `Failure`. +That is, there are only two possible implementations of `Try`: a `Try` instance where the operation has been successful, which is represented as `Success`; or a `Try` instance where the computation has failed with a `Throwable`, which is represented as `Failure`. With just this explanation you might think that we are talking about an `Either`, and you are not wrong. `Try` can be implemented in terms of `Either`, but its use cases are very different. diff --git a/modules/docs/arrow-docs/docs/docs/optics/optional/README.md b/modules/docs/arrow-docs/docs/docs/optics/optional/README.md index 22009bd7d00..a8543feaf8d 100644 --- a/modules/docs/arrow-docs/docs/docs/optics/optional/README.md +++ b/modules/docs/arrow-docs/docs/docs/optics/optional/README.md @@ -122,7 +122,7 @@ val lifted: (Try>) -> Try> = successT lifted(Try.Success(5 toT "World!")) ``` ```kotlin:ank -lifted(Try.Failure>(IllegalStateException("something went wrong"))) +lifted(Try.Failure(IllegalStateException("something went wrong"))) ``` ### Laws diff --git a/modules/docs/arrow-docs/docs/docs/optics/prism/README.md b/modules/docs/arrow-docs/docs/docs/optics/prism/README.md index ccb8be39f5f..412e5db1c8c 100644 --- a/modules/docs/arrow-docs/docs/docs/optics/prism/README.md +++ b/modules/docs/arrow-docs/docs/docs/optics/prism/README.md @@ -151,7 +151,7 @@ When dealing with polymorphic sum types like `Try` we can also have polymorph ```kotlin fun trySuccess(): PPrism, Try, A, B> = PPrism( - getOrModify = { aTry -> aTry.fold({ Try.Failure(it).left() }, { it.right() }) }, + getOrModify = { aTry -> aTry.fold({ Try.Failure(it).left() }, { it.right() }) }, reverseGet = { b -> Try.Success(b) } ) @@ -159,7 +159,7 @@ val liftSuccess: (Try) -> Try = pTrySuccess().lift(Int liftSuccess(Try.Success(5)) ``` ```kotlin -liftSuccess(Try.Failure(ArithmeticException("/ by zero"))) +liftSuccess(Try.Failure(ArithmeticException("/ by zero"))) ``` ### Laws