Skip to content

Commit

Permalink
Merge branch 'main' into ja-increase-currying-test-coverage-arrow-kt#…
Browse files Browse the repository at this point in the history
  • Loading branch information
serras authored Apr 3, 2023
2 parents 910baa4 + 246ec98 commit f22a23b
Show file tree
Hide file tree
Showing 18 changed files with 182 additions and 178 deletions.
6 changes: 0 additions & 6 deletions arrow-libs/core/arrow-core/api/arrow-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -1576,7 +1576,6 @@ public final class arrow/core/SequenceKt {
public static final fun crosswalk (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
public static final fun crosswalkMap (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Ljava/util/Map;
public static final fun crosswalkNull (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
public static final fun crosswalkNullList (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
public static final fun crosswalkT (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
public static final fun filterOption (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
public static final fun flatten (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
Expand All @@ -1599,7 +1598,6 @@ public final class arrow/core/SequenceKt {
public static final fun salign (Lkotlin/sequences/Sequence;Larrow/typeclasses/Semigroup;Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
public static final fun salign (Lkotlin/sequences/Sequence;Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence;
public static final fun separateEither (Lkotlin/sequences/Sequence;)Lkotlin/Pair;
public static final fun separateEitherToPair (Lkotlin/sequences/Sequence;)Lkotlin/Pair;
public static final fun separateValidated (Lkotlin/sequences/Sequence;)Lkotlin/Pair;
public static final fun sequence (Lkotlin/sequences/Sequence;)Larrow/core/Either;
public static final fun sequence (Lkotlin/sequences/Sequence;)Larrow/core/Option;
Expand All @@ -1618,15 +1616,11 @@ public final class arrow/core/SequenceKt {
public static final fun traverseValidated (Lkotlin/sequences/Sequence;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated;
public static final fun unalign (Lkotlin/sequences/Sequence;)Lkotlin/Pair;
public static final fun unalign (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair;
public static final fun unalignToPair (Lkotlin/sequences/Sequence;)Lkotlin/Pair;
public static final fun unalignToPair (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair;
public static final fun uniteEither (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
public static final fun uniteValidated (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
public static final fun unweave (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
public static final fun unzip (Lkotlin/sequences/Sequence;)Lkotlin/Pair;
public static final fun unzip (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair;
public static final fun unzipToPair (Lkotlin/sequences/Sequence;)Lkotlin/Pair;
public static final fun unzipToPair (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair;
public static final fun void (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
public static final fun widen (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
public static final fun zip (Lkotlin/sequences/Sequence;Lkotlin/sequences/Sequence;Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function3;)Lkotlin/sequences/Sequence;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,12 @@ public inline fun <A, B> Result<A>.flatMap(transform: (value: A) -> Result<B>):
* Compose a recovering [transform] operation on the failure value [Throwable] whilst flattening [Result].
* @see recoverCatching if you want run a function that catches and maps recovers with `(Throwable) -> A`.
*/
public inline fun <A> Result<A>.handleErrorWith(transform: (throwable: Throwable) -> Result<A>): Result<A> {
contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) }
return when (val exception = exceptionOrNull()) {
null -> this
else -> transform(exception)
}
}
@Deprecated(
"Prefer Kotlin Std Result.recoverCatching instead of handleErrorWith",
ReplaceWith("recoverCatching { transform(it).getOrThrow() }")
)
public inline fun <A> Result<A>.handleErrorWith(transform: (throwable: Throwable) -> Result<A>): Result<A> =
recoverCatching { transform(it).getOrThrow() }

/**
* Compose both:
Expand All @@ -44,6 +43,10 @@ public inline fun <A> Result<A>.handleErrorWith(transform: (throwable: Throwable
*
* Combining the powers of [flatMap] and [handleErrorWith].
*/
@Deprecated(
"Prefer Kotlin Std Result.fold instead of redeemWith",
ReplaceWith("fold(transform, handleErrorWith)")
)
public inline fun <A, B> Result<A>.redeemWith(
handleErrorWith: (throwable: Throwable) -> Result<B>,
transform: (value: A) -> Result<B>
Expand Down
149 changes: 40 additions & 109 deletions arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Sequence.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ package arrow.core
import arrow.core.Either.Left
import arrow.core.Either.Right
import arrow.core.raise.RaiseAccumulate
import arrow.core.raise.either
import arrow.core.raise.fold
import arrow.core.raise.option
import arrow.typeclasses.Monoid
import arrow.typeclasses.MonoidDeprecation
import arrow.typeclasses.Semigroup
Expand Down Expand Up @@ -389,10 +391,6 @@ public fun <A, K, V> Sequence<A>.crosswalkMap(f: (A) -> Map<K, V>): Map<K, Seque
}
}

@Deprecated(
"This function is actually terminal. Use crosswalkNullList(f) instead.",
ReplaceWith("this.crosswalk{a -> f(a).toList()}")
)
public fun <A, B> Sequence<A>.crosswalkNull(f: (A) -> B?): Sequence<B>? =
fold<A, Sequence<B>?>(emptySequence()) { bs, a ->
Ior.fromNullables(f(a), bs)?.fold(
Expand All @@ -402,15 +400,6 @@ public fun <A, B> Sequence<A>.crosswalkNull(f: (A) -> B?): Sequence<B>? =
)
}

public fun <A, B> Sequence<A>.crosswalkNullList(f: (A) -> B?): List<B>? =
fold<A, List<B>?>(emptyList()) { bs, a ->
Ior.fromNullables(f(a), bs)?.fold(
{ listOf(it) },
::identity,
{ l, r -> listOf(l) + r }
)
}

public fun <A> Sequence<Sequence<A>>.flatten(): Sequence<A> =
flatMap(::identity)

Expand Down Expand Up @@ -695,10 +684,6 @@ public fun <A> Sequence<A>.salign(
* @receiver Iterable of [Either]
* @return a tuple containing Sequence with [Either.Left] and another Sequence with its [Either.Right] values.
*/
@Deprecated(
"This function is actually terminal. Use separateEitherToPair instead.",
ReplaceWith("separateEitherToPair()")
)
public fun <A, B> Sequence<Either<A, B>>.separateEither(): Pair<Sequence<A>, Sequence<B>> =
fold(sequenceOf<A>() to sequenceOf<B>()) { (lefts, rights), either ->
when (either) {
Expand All @@ -707,15 +692,6 @@ public fun <A, B> Sequence<Either<A, B>>.separateEither(): Pair<Sequence<A>, Seq
}
}

public fun <A, B> Sequence<Either<A, B>>.separateEitherToPair(): Pair<List<A>, List<B>> =
fold(listOf<A>() to listOf<B>()) { (lefts, rights), either ->
when (either) {
is Left -> lefts + either.value to rights
is Right -> lefts to rights + either.value
}
}


/**
* Separate the inner [Validated] values into the [Validated.Invalid] and [Validated.Valid].
*
Expand All @@ -734,8 +710,12 @@ public fun <A, B> Sequence<Validated<A, B>>.separateValidated(): Pair<Sequence<A
}
}

@Deprecated(
"The sequence extension function is being deprecated in favor of the DSL.\n$NicheAPI",
ReplaceWith("let<Sequence<Either<E, A>>, Either<E, List<A>>> { s -> either<E, List<A>> { s.map<Either<E, A>, A> { it.bind<A>() }.toList<A>() } }", "arrow.core.raise.either")
)
public fun <E, A> Sequence<Either<E, A>>.sequence(): Either<E, List<A>> =
traverse(::identity)
let { s -> either { s.map { it.bind() }.toList() } }

@Deprecated(
"sequenceEither is being renamed to sequence to simplify the Arrow API",
Expand All @@ -744,8 +724,12 @@ public fun <E, A> Sequence<Either<E, A>>.sequence(): Either<E, List<A>> =
public fun <E, A> Sequence<Either<E, A>>.sequenceEither(): Either<E, Sequence<A>> =
sequence().map { it.asSequence() }

@Deprecated(
"The sequence extension function is being deprecated in favor of the Option DSL.\n$NicheAPI",
ReplaceWith("let<Sequence<Option<A>>, Option<List<A>>> { s -> option<List<A>> { s.map<Option<A>, A> { it.bind<A>() }.toList<A>() } }", "arrow.core.raise.option")
)
public fun <A> Sequence<Option<A>>.sequence(): Option<List<A>> =
traverse(::identity)
let { s -> option { s.map { it.bind() }.toList() } }

@Deprecated(
"sequenceOption is being renamed to sequence to simplify the Arrow API",
Expand Down Expand Up @@ -803,21 +787,14 @@ public fun <A> Sequence<A>.split(): Pair<Sequence<A>, A>? =
public fun <A> Sequence<A>.tail(): Sequence<A> =
drop(1)

@Deprecated(
"Traverse for Sequence is being deprecated in favor of Either DSL.\n$NicheAPI",
ReplaceWith("let<Sequence<A>, Either<E, List<B>>> { s -> either<E, List<B>> { s.map<A, B> { f(it).bind<B>() }.toList<B>() } }", "arrow.core.raise.either")
)
@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
public fun <E, A, B> Sequence<A>.traverse(f: (A) -> Either<E, B>): Either<E, List<B>> {
// Note: Using a mutable list here avoids the stackoverflows one can accidentally create when using
// Sequence.plus instead. But we don't convert the sequence to a list beforehand to avoid
// forcing too much of the sequence to be evaluated.
val acc = mutableListOf<B>()
forEach { a ->
when (val res = f(a)) {
is Right -> acc.add(res.value)
is Left -> return@traverse res
}
}
return acc.toList().right()
}
public fun <E, A, B> Sequence<A>.traverse(f: (A) -> Either<E, B>): Either<E, List<B>> =
let { s -> either { s.map { f(it).bind() }.toList() } }

@Deprecated(
"traverseEither is being renamed to traverse to simplify the Arrow API",
Expand All @@ -826,21 +803,14 @@ public fun <E, A, B> Sequence<A>.traverse(f: (A) -> Either<E, B>): Either<E, Lis
public fun <E, A, B> Sequence<A>.traverseEither(f: (A) -> Either<E, B>): Either<E, Sequence<B>> =
traverse(f).map { it.asSequence() }

@Deprecated(
"Traverse for Sequence is being deprecated in favor of Either DSL.\n$NicheAPI",
ReplaceWith("let<Sequence<A>, Option<List<B>>> { s -> option<List<B>> { s.map<A, B> { f(it).bind<B>() }.toList<B>() } }", "arrow.core.raise.option")
)
@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
public fun <A, B> Sequence<A>.traverse(f: (A) -> Option<B>): Option<List<B>> {
// Note: Using a mutable list here avoids the stackoverflows one can accidentally create when using
// Sequence.plus instead. But we don't convert the sequence to a list beforehand to avoid
// forcing too much of the sequence to be evaluated.
val acc = mutableListOf<B>()
forEach { a ->
when (val res = f(a)) {
is Some -> acc.add(res.value)
is None -> return@traverse res
}
}
return Some(acc)
}
public fun <A, B> Sequence<A>.traverse(f: (A) -> Option<B>): Option<List<B>> =
let { s -> option { s.map { f(it).bind() }.toList() } }

@Deprecated(
"traverseOption is being renamed to traverse to simplify the Arrow API",
Expand Down Expand Up @@ -898,71 +868,50 @@ public fun <E, A, B> Sequence<A>.traverseValidated(
): Validated<E, Sequence<B>> =
traverse(semigroup, f).map { it.asSequence() }

@Deprecated(
"This function is actually terminal. Use unalignToPair instead.",
ReplaceWith("unalignToPair()")
)
public fun <A, B> Sequence<Ior<A, B>>.unalign(): Pair<Sequence<A>, Sequence<B>> =
fold(emptySequence<A>() to emptySequence()) { (l, r), x ->
x.fold(
{ l + it to r },
{ l to r + it },
{ a, b -> l + a to r + b }
)
}

/**
* splits an union into its component parts.
*
* ```kotlin
* import arrow.core.bothIor
* import arrow.core.leftIor
* import arrow.core.unalignToPair
* import arrow.core.unalign
*
* fun main(args: Array<String>) {
* //sampleStart
* val result = sequenceOf(("A" to 1).bothIor(), ("B" to 2).bothIor(), "C".leftIor()).unalignToPair()
* val result = sequenceOf(("A" to 1).bothIor(), ("B" to 2).bothIor(), "C".leftIor()).unalign()
* //sampleEnd
* println("(${result.first}, ${result.second})")
* }
* ```
* <!--- KNIT example-sequence-12.kt -->
*/
public fun <A, B> Sequence<Ior<A, B>>.unalignToPair(): Pair<List<A>, List<B>> =
fold(emptyList<A>() to emptyList()) { (l, r), x ->
public fun <A, B> Sequence<Ior<A, B>>.unalign(): Pair<Sequence<A>, Sequence<B>> =
fold(emptySequence<A>() to emptySequence()) { (l, r), x ->
x.fold(
{ l + it to r },
{ l to r + it },
{ a, b -> l + a to r + b }
)
}


@Deprecated(
"This function is actually terminal. Use unalignToPair instead.",
ReplaceWith("unalignToPair(fa)")
)
public fun <A, B, C> Sequence<C>.unalign(fa: (C) -> Ior<A, B>): Pair<Sequence<A>, Sequence<B>> =
map(fa).unalign()

/**
* after applying the given function, splits the resulting union shaped structure into its components parts
*
* ```kotlin
* import arrow.core.leftIor
* import arrow.core.unalignToPair
* import arrow.core.unalign
*
* fun main(args: Array<String>) {
* //sampleStart
* val result = sequenceOf(1, 2, 3).unalignToPair { it.leftIor() }
* val result = sequenceOf(1, 2, 3).unalign { it.leftIor() }
* //sampleEnd
* println("(${result.first.toList()}, ${result.second.toList()})")
* }
* ```
* <!--- KNIT example-sequence-13.kt -->
*/
public fun <A, B, C> Sequence<C>.unalignToPair(fa: (C) -> Ior<A, B>): Pair<List<A>, List<B>> =
map(fa).unalignToPair()
public fun <A, B, C> Sequence<C>.unalign(fa: (C) -> Ior<A, B>): Pair<Sequence<A>, Sequence<B>> =
map(fa).unalign()

@Deprecated(
NicheAPI + "Prefer using flatMap + fold",
Expand Down Expand Up @@ -1007,53 +956,36 @@ public fun <A, B> Sequence<A>.unweave(ffa: (A) -> Sequence<B>): Sequence<B> =
ffa(a).interleave(fa.unweave(ffa))
} ?: emptySequence()

@Deprecated(
"This function is actually terminal. Use unzipToPair instead.",
ReplaceWith("unzipToPair()")
)
public fun <A, B> Sequence<Pair<A, B>>.unzip(): Pair<Sequence<A>, Sequence<B>> =
fold(emptySequence<A>() to emptySequence()) { (l, r), x ->
l + x.first to r + x.second
}

/**
* unzips the structure holding the resulting elements in an `Pair`
*
* ```kotlin
* import arrow.core.unzipToPair
* import arrow.core.unzip
*
* fun main(args: Array<String>) {
* //sampleStart
* val result = sequenceOf("A" to 1, "B" to 2).unzipToPair()
* val result = sequenceOf("A" to 1, "B" to 2).unzip()
* //sampleEnd
* println("(${result.first}, ${result.second})")
* }
* ```
* <!--- KNIT example-sequence-15.kt -->
*/
public fun <A, B> Sequence<Pair<A, B>>.unzipToPair(): Pair<List<A>, List<B>> =
fold(emptyList<A>() to emptyList()) { (l, r), x ->
public fun <A, B> Sequence<Pair<A, B>>.unzip(): Pair<Sequence<A>, Sequence<B>> =
fold(emptySequence<A>() to emptySequence()) { (l, r), x ->
l + x.first to r + x.second
}


@Deprecated(
"This function is actually terminal. Use unzipToPair instead.",
ReplaceWith("unzipToPair(fc)")
)
public fun <A, B, C> Sequence<C>.unzip(fc: (C) -> Pair<A, B>): Pair<Sequence<A>, Sequence<B>> =
map(fc).unzip()

/**
* after applying the given function unzip the resulting structure into its elements.
*
* ```kotlin
* import arrow.core.unzipToPair
* import arrow.core.unzip
*
* fun main(args: Array<String>) {
* //sampleStart
* val result =
* sequenceOf("A:1", "B:2", "C:3").unzipToPair { e ->
* sequenceOf("A:1", "B:2", "C:3").unzip { e ->
* e.split(":").let {
* it.first() to it.last()
* }
Expand All @@ -1064,9 +996,8 @@ public fun <A, B, C> Sequence<C>.unzip(fc: (C) -> Pair<A, B>): Pair<Sequence<A>,
* ```
* <!--- KNIT example-sequence-16.kt -->
*/
public fun <A, B, C> Sequence<C>.unzipToPair(fc: (C) -> Pair<A, B>): Pair<List<A>, List<B>> =
map(fc).unzipToPair()

public fun <A, B, C> Sequence<C>.unzip(fc: (C) -> Pair<A, B>): Pair<Sequence<A>, Sequence<B>> =
map(fc).unzip()

@Deprecated(
"void is being deprecated in favor of simple Iterable.map.\n$NicheAPI",
Expand Down
Loading

0 comments on commit f22a23b

Please sign in to comment.