diff --git a/arrow-libs/core/arrow-core-high-arity/src/commonMain/kotlin/arrow/core/NonEmptyList.kt b/arrow-libs/core/arrow-core-high-arity/src/commonMain/kotlin/arrow/core/NonEmptyList.kt index c15b2ff31f..a5b916d621 100644 --- a/arrow-libs/core/arrow-core-high-arity/src/commonMain/kotlin/arrow/core/NonEmptyList.kt +++ b/arrow-libs/core/arrow-core-high-arity/src/commonMain/kotlin/arrow/core/NonEmptyList.kt @@ -1,6 +1,5 @@ @file:JvmName("NonEmptyListHighArityKt") -@file:OptIn(ExperimentalContracts::class, PotentiallyUnsafeNonEmptyOperation::class) -@file:Suppress("WRONG_INVOCATION_KIND", "LEAKED_IN_PLACE_LAMBDA") +@file:OptIn(ExperimentalContracts::class) package arrow.core @@ -23,7 +22,22 @@ public inline fun NonEmptyList R, ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(t1.all, t2.all, t3.all, t4.all, t5.all, t6.all, t7.all, t8.all, t9.all, t10.all, map).wrapAsNonEmptyListOrThrow() + val i0 = iterator() + val i1 = t1.iterator() + val i2 = t2.iterator() + val i3 = t3.iterator() + val i4 = t4.iterator() + val i5 = t5.iterator() + val i6 = t6.iterator() + val i7 = t7.iterator() + val i8 = t8.iterator() + val i9 = t9.iterator() + val i10 = t10.iterator() + return buildNonEmptyList(minOf(size, t1.size, t2.size, t3.size, t4.size, t5.size, t6.size, t7.size, t8.size, t9.size, t10.size)) { + do add(map(i0.next(), i1.next(), i2.next(), i3.next(), i4.next(), i5.next(), i6.next(), i7.next(), i8.next(), i9.next(), i10.next())) + while (i0.hasNext() && i1.hasNext() && i2.hasNext() && i3.hasNext() && i4.hasNext() && i5.hasNext() && i6.hasNext() && i7.hasNext() && i8.hasNext() && i9.hasNext() && i10.hasNext()) + this + } } public inline fun NonEmptyList.zip( @@ -41,7 +55,23 @@ public inline fun NonEmptyL map: (A, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R, ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(t1.all, t2.all, t3.all, t4.all, t5.all, t6.all, t7.all, t8.all, t9.all, t10.all, t11.all, map).wrapAsNonEmptyListOrThrow() + val i0 = iterator() + val i1 = t1.iterator() + val i2 = t2.iterator() + val i3 = t3.iterator() + val i4 = t4.iterator() + val i5 = t5.iterator() + val i6 = t6.iterator() + val i7 = t7.iterator() + val i8 = t8.iterator() + val i9 = t9.iterator() + val i10 = t10.iterator() + val i11 = t11.iterator() + return buildNonEmptyList(minOf(size, t1.size, t2.size, t3.size, t4.size, t5.size, t6.size, t7.size, t8.size, t9.size, t10.size, t11.size)) { + do add(map(i0.next(), i1.next(), i2.next(), i3.next(), i4.next(), i5.next(), i6.next(), i7.next(), i8.next(), i9.next(), i10.next(), i11.next())) + while (i0.hasNext() && i1.hasNext() && i2.hasNext() && i3.hasNext() && i4.hasNext() && i5.hasNext() && i6.hasNext() && i7.hasNext() && i8.hasNext() && i9.hasNext() && i10.hasNext() && i11.hasNext()) + this + } } public inline fun NonEmptyList.zip( @@ -60,7 +90,24 @@ public inline fun NonE map: (A, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R, ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(t1.all, t2.all, t3.all, t4.all, t5.all, t6.all, t7.all, t8.all, t9.all, t10.all, t11.all, t12.all, map).wrapAsNonEmptyListOrThrow() + val i0 = iterator() + val i1 = t1.iterator() + val i2 = t2.iterator() + val i3 = t3.iterator() + val i4 = t4.iterator() + val i5 = t5.iterator() + val i6 = t6.iterator() + val i7 = t7.iterator() + val i8 = t8.iterator() + val i9 = t9.iterator() + val i10 = t10.iterator() + val i11 = t11.iterator() + val i12 = t12.iterator() + return buildNonEmptyList(minOf(size, t1.size, t2.size, t3.size, t4.size, t5.size, t6.size, t7.size, t8.size, t9.size, t10.size, t11.size, t12.size)) { + do add(map(i0.next(), i1.next(), i2.next(), i3.next(), i4.next(), i5.next(), i6.next(), i7.next(), i8.next(), i9.next(), i10.next(), i11.next(), i12.next())) + while (i0.hasNext() && i1.hasNext() && i2.hasNext() && i3.hasNext() && i4.hasNext() && i5.hasNext() && i6.hasNext() && i7.hasNext() && i8.hasNext() && i9.hasNext() && i10.hasNext() && i11.hasNext() && i12.hasNext()) + this + } } public inline fun NonEmptyList.zip( @@ -80,7 +127,25 @@ public inline fun map: (A, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R, ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(t1.all, t2.all, t3.all, t4.all, t5.all, t6.all, t7.all, t8.all, t9.all, t10.all, t11.all, t12.all, t13.all, map).wrapAsNonEmptyListOrThrow() + val i0 = iterator() + val i1 = t1.iterator() + val i2 = t2.iterator() + val i3 = t3.iterator() + val i4 = t4.iterator() + val i5 = t5.iterator() + val i6 = t6.iterator() + val i7 = t7.iterator() + val i8 = t8.iterator() + val i9 = t9.iterator() + val i10 = t10.iterator() + val i11 = t11.iterator() + val i12 = t12.iterator() + val i13 = t13.iterator() + return buildNonEmptyList(minOf(size, t1.size, t2.size, t3.size, t4.size, t5.size, t6.size, t7.size, t8.size, t9.size, t10.size, t11.size, t12.size, t13.size)) { + do add(map(i0.next(), i1.next(), i2.next(), i3.next(), i4.next(), i5.next(), i6.next(), i7.next(), i8.next(), i9.next(), i10.next(), i11.next(), i12.next(), i13.next())) + while (i0.hasNext() && i1.hasNext() && i2.hasNext() && i3.hasNext() && i4.hasNext() && i5.hasNext() && i6.hasNext() && i7.hasNext() && i8.hasNext() && i9.hasNext() && i10.hasNext() && i11.hasNext() && i12.hasNext() && i13.hasNext()) + this + } } public inline fun NonEmptyList.zip( @@ -101,7 +166,26 @@ public inline fun R, ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(t1.all, t2.all, t3.all, t4.all, t5.all, t6.all, t7.all, t8.all, t9.all, t10.all, t11.all, t12.all, t13.all, t14.all, map).wrapAsNonEmptyListOrThrow() + val i0 = iterator() + val i1 = t1.iterator() + val i2 = t2.iterator() + val i3 = t3.iterator() + val i4 = t4.iterator() + val i5 = t5.iterator() + val i6 = t6.iterator() + val i7 = t7.iterator() + val i8 = t8.iterator() + val i9 = t9.iterator() + val i10 = t10.iterator() + val i11 = t11.iterator() + val i12 = t12.iterator() + val i13 = t13.iterator() + val i14 = t14.iterator() + return buildNonEmptyList(minOf(size, t1.size, t2.size, t3.size, t4.size, t5.size, t6.size, t7.size, t8.size, t9.size, t10.size, t11.size, t12.size, t13.size, t14.size)) { + do add(map(i0.next(), i1.next(), i2.next(), i3.next(), i4.next(), i5.next(), i6.next(), i7.next(), i8.next(), i9.next(), i10.next(), i11.next(), i12.next(), i13.next(), i14.next())) + while (i0.hasNext() && i1.hasNext() && i2.hasNext() && i3.hasNext() && i4.hasNext() && i5.hasNext() && i6.hasNext() && i7.hasNext() && i8.hasNext() && i9.hasNext() && i10.hasNext() && i11.hasNext() && i12.hasNext() && i13.hasNext() && i14.hasNext()) + this + } } public inline fun NonEmptyList.zip( @@ -123,7 +207,27 @@ public inline fun R, ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(t1.all, t2.all, t3.all, t4.all, t5.all, t6.all, t7.all, t8.all, t9.all, t10.all, t11.all, t12.all, t13.all, t14.all, t15.all, map).wrapAsNonEmptyListOrThrow() + val i0 = iterator() + val i1 = t1.iterator() + val i2 = t2.iterator() + val i3 = t3.iterator() + val i4 = t4.iterator() + val i5 = t5.iterator() + val i6 = t6.iterator() + val i7 = t7.iterator() + val i8 = t8.iterator() + val i9 = t9.iterator() + val i10 = t10.iterator() + val i11 = t11.iterator() + val i12 = t12.iterator() + val i13 = t13.iterator() + val i14 = t14.iterator() + val i15 = t15.iterator() + return buildNonEmptyList(minOf(size, t1.size, t2.size, t3.size, t4.size, t5.size, t6.size, t7.size, t8.size, t9.size, t10.size, t11.size, t12.size, t13.size, t14.size, t15.size)) { + do add(map(i0.next(), i1.next(), i2.next(), i3.next(), i4.next(), i5.next(), i6.next(), i7.next(), i8.next(), i9.next(), i10.next(), i11.next(), i12.next(), i13.next(), i14.next(), i15.next())) + while (i0.hasNext() && i1.hasNext() && i2.hasNext() && i3.hasNext() && i4.hasNext() && i5.hasNext() && i6.hasNext() && i7.hasNext() && i8.hasNext() && i9.hasNext() && i10.hasNext() && i11.hasNext() && i12.hasNext() && i13.hasNext() && i14.hasNext() && i15.hasNext()) + this + } } public inline fun NonEmptyList.zip( @@ -146,7 +250,28 @@ public inline fun R, ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(t1.all, t2.all, t3.all, t4.all, t5.all, t6.all, t7.all, t8.all, t9.all, t10.all, t11.all, t12.all, t13.all, t14.all, t15.all, t16.all, map).wrapAsNonEmptyListOrThrow() + val i0 = iterator() + val i1 = t1.iterator() + val i2 = t2.iterator() + val i3 = t3.iterator() + val i4 = t4.iterator() + val i5 = t5.iterator() + val i6 = t6.iterator() + val i7 = t7.iterator() + val i8 = t8.iterator() + val i9 = t9.iterator() + val i10 = t10.iterator() + val i11 = t11.iterator() + val i12 = t12.iterator() + val i13 = t13.iterator() + val i14 = t14.iterator() + val i15 = t15.iterator() + val i16 = t16.iterator() + return buildNonEmptyList(minOf(size, t1.size, t2.size, t3.size, t4.size, t5.size, t6.size, t7.size, t8.size, t9.size, t10.size, t11.size, t12.size, t13.size, t14.size, t15.size, t16.size)) { + do add(map(i0.next(), i1.next(), i2.next(), i3.next(), i4.next(), i5.next(), i6.next(), i7.next(), i8.next(), i9.next(), i10.next(), i11.next(), i12.next(), i13.next(), i14.next(), i15.next(), i16.next())) + while (i0.hasNext() && i1.hasNext() && i2.hasNext() && i3.hasNext() && i4.hasNext() && i5.hasNext() && i6.hasNext() && i7.hasNext() && i8.hasNext() && i9.hasNext() && i10.hasNext() && i11.hasNext() && i12.hasNext() && i13.hasNext() && i14.hasNext() && i15.hasNext() && i16.hasNext()) + this + } } public inline fun NonEmptyList.zip( @@ -170,7 +295,29 @@ public inline fun R, ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(t1.all, t2.all, t3.all, t4.all, t5.all, t6.all, t7.all, t8.all, t9.all, t10.all, t11.all, t12.all, t13.all, t14.all, t15.all, t16.all, t17.all, map).wrapAsNonEmptyListOrThrow() + val i0 = iterator() + val i1 = t1.iterator() + val i2 = t2.iterator() + val i3 = t3.iterator() + val i4 = t4.iterator() + val i5 = t5.iterator() + val i6 = t6.iterator() + val i7 = t7.iterator() + val i8 = t8.iterator() + val i9 = t9.iterator() + val i10 = t10.iterator() + val i11 = t11.iterator() + val i12 = t12.iterator() + val i13 = t13.iterator() + val i14 = t14.iterator() + val i15 = t15.iterator() + val i16 = t16.iterator() + val i17 = t17.iterator() + return buildNonEmptyList(minOf(size, t1.size, t2.size, t3.size, t4.size, t5.size, t6.size, t7.size, t8.size, t9.size, t10.size, t11.size, t12.size, t13.size, t14.size, t15.size, t16.size, t17.size)) { + do add(map(i0.next(), i1.next(), i2.next(), i3.next(), i4.next(), i5.next(), i6.next(), i7.next(), i8.next(), i9.next(), i10.next(), i11.next(), i12.next(), i13.next(), i14.next(), i15.next(), i16.next(), i17.next())) + while (i0.hasNext() && i1.hasNext() && i2.hasNext() && i3.hasNext() && i4.hasNext() && i5.hasNext() && i6.hasNext() && i7.hasNext() && i8.hasNext() && i9.hasNext() && i10.hasNext() && i11.hasNext() && i12.hasNext() && i13.hasNext() && i14.hasNext() && i15.hasNext() && i16.hasNext() && i17.hasNext()) + this + } } public inline fun NonEmptyList.zip( @@ -195,7 +342,30 @@ public inline fun R, ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(t1.all, t2.all, t3.all, t4.all, t5.all, t6.all, t7.all, t8.all, t9.all, t10.all, t11.all, t12.all, t13.all, t14.all, t15.all, t16.all, t17.all, t18.all, map).wrapAsNonEmptyListOrThrow() + val i0 = iterator() + val i1 = t1.iterator() + val i2 = t2.iterator() + val i3 = t3.iterator() + val i4 = t4.iterator() + val i5 = t5.iterator() + val i6 = t6.iterator() + val i7 = t7.iterator() + val i8 = t8.iterator() + val i9 = t9.iterator() + val i10 = t10.iterator() + val i11 = t11.iterator() + val i12 = t12.iterator() + val i13 = t13.iterator() + val i14 = t14.iterator() + val i15 = t15.iterator() + val i16 = t16.iterator() + val i17 = t17.iterator() + val i18 = t18.iterator() + return buildNonEmptyList(minOf(size, t1.size, t2.size, t3.size, t4.size, t5.size, t6.size, t7.size, t8.size, t9.size, t10.size, t11.size, t12.size, t13.size, t14.size, t15.size, t16.size, t17.size, t18.size)) { + do add(map(i0.next(), i1.next(), i2.next(), i3.next(), i4.next(), i5.next(), i6.next(), i7.next(), i8.next(), i9.next(), i10.next(), i11.next(), i12.next(), i13.next(), i14.next(), i15.next(), i16.next(), i17.next(), i18.next())) + while (i0.hasNext() && i1.hasNext() && i2.hasNext() && i3.hasNext() && i4.hasNext() && i5.hasNext() && i6.hasNext() && i7.hasNext() && i8.hasNext() && i9.hasNext() && i10.hasNext() && i11.hasNext() && i12.hasNext() && i13.hasNext() && i14.hasNext() && i15.hasNext() && i16.hasNext() && i17.hasNext() && i18.hasNext()) + this + } } public inline fun NonEmptyList.zip( @@ -221,7 +391,31 @@ public inline fun R, ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(t1.all, t2.all, t3.all, t4.all, t5.all, t6.all, t7.all, t8.all, t9.all, t10.all, t11.all, t12.all, t13.all, t14.all, t15.all, t16.all, t17.all, t18.all, t19.all, map).wrapAsNonEmptyListOrThrow() + val i0 = iterator() + val i1 = t1.iterator() + val i2 = t2.iterator() + val i3 = t3.iterator() + val i4 = t4.iterator() + val i5 = t5.iterator() + val i6 = t6.iterator() + val i7 = t7.iterator() + val i8 = t8.iterator() + val i9 = t9.iterator() + val i10 = t10.iterator() + val i11 = t11.iterator() + val i12 = t12.iterator() + val i13 = t13.iterator() + val i14 = t14.iterator() + val i15 = t15.iterator() + val i16 = t16.iterator() + val i17 = t17.iterator() + val i18 = t18.iterator() + val i19 = t19.iterator() + return buildNonEmptyList(minOf(size, t1.size, t2.size, t3.size, t4.size, t5.size, t6.size, t7.size, t8.size, t9.size, t10.size, t11.size, t12.size, t13.size, t14.size, t15.size, t16.size, t17.size, t18.size, t19.size)) { + do add(map(i0.next(), i1.next(), i2.next(), i3.next(), i4.next(), i5.next(), i6.next(), i7.next(), i8.next(), i9.next(), i10.next(), i11.next(), i12.next(), i13.next(), i14.next(), i15.next(), i16.next(), i17.next(), i18.next(), i19.next())) + while (i0.hasNext() && i1.hasNext() && i2.hasNext() && i3.hasNext() && i4.hasNext() && i5.hasNext() && i6.hasNext() && i7.hasNext() && i8.hasNext() && i9.hasNext() && i10.hasNext() && i11.hasNext() && i12.hasNext() && i13.hasNext() && i14.hasNext() && i15.hasNext() && i16.hasNext() && i17.hasNext() && i18.hasNext() && i19.hasNext()) + this + } } public inline fun NonEmptyList.zip( @@ -248,5 +442,30 @@ public inline fun R, ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(t1.all, t2.all, t3.all, t4.all, t5.all, t6.all, t7.all, t8.all, t9.all, t10.all, t11.all, t12.all, t13.all, t14.all, t15.all, t16.all, t17.all, t18.all, t19.all, t20.all, map).wrapAsNonEmptyListOrThrow() + val i0 = iterator() + val i1 = t1.iterator() + val i2 = t2.iterator() + val i3 = t3.iterator() + val i4 = t4.iterator() + val i5 = t5.iterator() + val i6 = t6.iterator() + val i7 = t7.iterator() + val i8 = t8.iterator() + val i9 = t9.iterator() + val i10 = t10.iterator() + val i11 = t11.iterator() + val i12 = t12.iterator() + val i13 = t13.iterator() + val i14 = t14.iterator() + val i15 = t15.iterator() + val i16 = t16.iterator() + val i17 = t17.iterator() + val i18 = t18.iterator() + val i19 = t19.iterator() + val i20 = t20.iterator() + return buildNonEmptyList(minOf(size, t1.size, t2.size, t3.size, t4.size, t5.size, t6.size, t7.size, t8.size, t9.size, t10.size, t11.size, t12.size, t13.size, t14.size, t15.size, t16.size, t17.size, t18.size, t19.size, t20.size)) { + do add(map(i0.next(), i1.next(), i2.next(), i3.next(), i4.next(), i5.next(), i6.next(), i7.next(), i8.next(), i9.next(), i10.next(), i11.next(), i12.next(), i13.next(), i14.next(), i15.next(), i16.next(), i17.next(), i18.next(), i19.next(), i20.next())) + while (i0.hasNext() && i1.hasNext() && i2.hasNext() && i3.hasNext() && i4.hasNext() && i5.hasNext() && i6.hasNext() && i7.hasNext() && i8.hasNext() && i9.hasNext() && i10.hasNext() && i11.hasNext() && i12.hasNext() && i13.hasNext() && i14.hasNext() && i15.hasNext() && i16.hasNext() && i17.hasNext() && i18.hasNext() && i19.hasNext() && i20.hasNext()) + this + } } diff --git a/arrow-libs/core/arrow-core/api/android/arrow-core.api b/arrow-libs/core/arrow-core/api/android/arrow-core.api index 4f419e93f2..7cad018a18 100644 --- a/arrow-libs/core/arrow-core/api/android/arrow-core.api +++ b/arrow-libs/core/arrow-core/api/android/arrow-core.api @@ -349,6 +349,45 @@ public final class arrow/core/MemoizedDeepRecursiveFunctionKt { public static synthetic fun MemoizedDeepRecursiveFunction$default (Larrow/core/MemoizationCache;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlin/DeepRecursiveFunction; } +public abstract interface class arrow/core/MonotoneCollectionBuilder { + public abstract fun _add (Ljava/lang/Object;)V + public abstract fun _addAll (Ljava/util/Collection;)V +} + +public abstract interface class arrow/core/MonotoneCollectionBuilder$NonEmpty { +} + +public final class arrow/core/MonotoneCollectionBuilderKt { + public static final fun add (Larrow/core/MonotoneCollectionBuilder;Ljava/lang/Object;)V + public static final fun addAll (Larrow/core/MonotoneCollectionBuilder;Larrow/core/NonEmptyCollection;)V + public static final fun addAll (Larrow/core/MonotoneCollectionBuilder;Ljava/lang/Iterable;)V + public static final fun addAll (Larrow/core/MonotoneCollectionBuilder;Ljava/util/Collection;)V + public static final fun asNonEmptyList (Ljava/util/List;)Ljava/util/List; + public static final fun asNonEmptySet (Ljava/util/Set;)Ljava/util/Set; + public static final fun buildNonEmptyList (ILkotlin/jvm/functions/Function1;)Ljava/util/List; + public static final fun buildNonEmptyList (Lkotlin/jvm/functions/Function1;)Ljava/util/List; + public static final fun buildNonEmptySet (ILkotlin/jvm/functions/Function1;)Ljava/util/Set; + public static final fun buildNonEmptySet (Lkotlin/jvm/functions/Function1;)Ljava/util/Set; +} + +public abstract interface class arrow/core/MonotoneMutableList : arrow/core/MonotoneCollectionBuilder, java/util/List, kotlin/jvm/internal/markers/KMappedMarker { + public static final field Companion Larrow/core/MonotoneMutableList$Companion; +} + +public final class arrow/core/MonotoneMutableList$Companion { + public final fun invoke ()Larrow/core/MonotoneMutableList; + public final fun invoke (I)Larrow/core/MonotoneMutableList; +} + +public abstract interface class arrow/core/MonotoneMutableSet : arrow/core/MonotoneCollectionBuilder, java/util/Set, kotlin/jvm/internal/markers/KMappedMarker { + public static final field Companion Larrow/core/MonotoneMutableSet$Companion; +} + +public final class arrow/core/MonotoneMutableSet$Companion { + public final fun invoke ()Larrow/core/MonotoneMutableSet; + public final fun invoke (I)Larrow/core/MonotoneMutableSet; +} + public abstract interface class arrow/core/NonEmptyCollection : java/util/Collection, kotlin/jvm/internal/markers/KMappedMarker { public abstract fun distinct-1X0FA-Y ()Ljava/util/List; public abstract fun distinctBy-0-xjo5U (Lkotlin/jvm/functions/Function1;)Ljava/util/List; @@ -371,7 +410,9 @@ public final class arrow/core/NonEmptyCollection$DefaultImpls { public static fun distinctBy-0-xjo5U (Larrow/core/NonEmptyCollection;Lkotlin/jvm/functions/Function1;)Ljava/util/List; public static fun firstOrNull (Larrow/core/NonEmptyCollection;)Ljava/lang/Object; public static fun flatMap-0-xjo5U (Larrow/core/NonEmptyCollection;Lkotlin/jvm/functions/Function1;)Ljava/util/List; + public static fun getHead (Larrow/core/NonEmptyCollection;)Ljava/lang/Object; public static fun isEmpty (Larrow/core/NonEmptyCollection;)Z + public static fun lastOrNull (Larrow/core/NonEmptyCollection;)Ljava/lang/Object; public static fun map-0-xjo5U (Larrow/core/NonEmptyCollection;Lkotlin/jvm/functions/Function1;)Ljava/util/List; public static fun mapIndexed-0-xjo5U (Larrow/core/NonEmptyCollection;Lkotlin/jvm/functions/Function2;)Ljava/util/List; public static fun toNonEmptyList-1X0FA-Y (Larrow/core/NonEmptyCollection;)Ljava/util/List; diff --git a/arrow-libs/core/arrow-core/api/arrow-core.klib.api b/arrow-libs/core/arrow-core/api/arrow-core.klib.api index 454d0b1d31..bb3db2f4fd 100644 --- a/arrow-libs/core/arrow-core/api/arrow-core.klib.api +++ b/arrow-libs/core/arrow-core/api/arrow-core.klib.api @@ -39,16 +39,36 @@ abstract interface <#A: in kotlin/Any?> arrow.core.raise/Raise { // arrow.core.r open suspend fun <#A1: kotlin/Any?> (kotlin.coroutines/SuspendFunction1, #A1>).invoke(): #A1 // arrow.core.raise/Raise.invoke|invoke@kotlin.coroutines.SuspendFunction1,0:0>(){0§}[0] } +abstract interface <#A: in kotlin/Any?> arrow.core/MonotoneCollectionBuilder { // arrow.core/MonotoneCollectionBuilder|null[0] + abstract fun _add(#A) // arrow.core/MonotoneCollectionBuilder._add|_add(1:0){}[0] + abstract fun _addAll(kotlin.collections/Collection<#A>) // arrow.core/MonotoneCollectionBuilder._addAll|_addAll(kotlin.collections.Collection<1:0>){}[0] + + abstract interface NonEmpty // arrow.core/MonotoneCollectionBuilder.NonEmpty|null[0] +} + abstract interface <#A: kotlin/Any?, #B: kotlin/Any?> arrow.core/MemoizationCache { // arrow.core/MemoizationCache|null[0] abstract fun get(#A): #B? // arrow.core/MemoizationCache.get|get(1:0){}[0] abstract fun set(#A, #B): #B // arrow.core/MemoizationCache.set|set(1:0;1:1){}[0] } +abstract interface <#A: kotlin/Any?> arrow.core/MonotoneMutableList : arrow.core/MonotoneCollectionBuilder<#A>, kotlin.collections/List<#A> { // arrow.core/MonotoneMutableList|null[0] + final object Companion { // arrow.core/MonotoneMutableList.Companion|null[0] + final fun <#A2: kotlin/Any?> invoke(): arrow.core/MonotoneMutableList<#A2> // arrow.core/MonotoneMutableList.Companion.invoke|invoke(){0§}[0] + final fun <#A2: kotlin/Any?> invoke(kotlin/Int): arrow.core/MonotoneMutableList<#A2> // arrow.core/MonotoneMutableList.Companion.invoke|invoke(kotlin.Int){0§}[0] + } +} + +abstract interface <#A: kotlin/Any?> arrow.core/MonotoneMutableSet : arrow.core/MonotoneCollectionBuilder<#A>, kotlin.collections/Set<#A> { // arrow.core/MonotoneMutableSet|null[0] + final object Companion { // arrow.core/MonotoneMutableSet.Companion|null[0] + final fun <#A2: kotlin/Any?> invoke(): arrow.core/MonotoneMutableSet<#A2> // arrow.core/MonotoneMutableSet.Companion.invoke|invoke(){0§}[0] + final fun <#A2: kotlin/Any?> invoke(kotlin/Int): arrow.core/MonotoneMutableSet<#A2> // arrow.core/MonotoneMutableSet.Companion.invoke|invoke(kotlin.Int){0§}[0] + } +} + abstract interface <#A: out kotlin/Any?> arrow.core/NonEmptyCollection : kotlin.collections/Collection<#A> { // arrow.core/NonEmptyCollection|null[0] - abstract val head // arrow.core/NonEmptyCollection.head|{}head[0] - abstract fun (): #A // arrow.core/NonEmptyCollection.head.|(){}[0] + open val head // arrow.core/NonEmptyCollection.head|{}head[0] + open fun (): #A // arrow.core/NonEmptyCollection.head.|(){}[0] - abstract fun lastOrNull(): #A // arrow.core/NonEmptyCollection.lastOrNull|lastOrNull(){}[0] abstract fun plus(#A): arrow.core/NonEmptyCollection<#A> // arrow.core/NonEmptyCollection.plus|plus(1:0){}[0] abstract fun plus(kotlin.collections/Iterable<#A>): arrow.core/NonEmptyCollection<#A> // arrow.core/NonEmptyCollection.plus|plus(kotlin.collections.Iterable<1:0>){}[0] open fun <#A1: kotlin/Any?> distinctBy(kotlin/Function1<#A, #A1>): arrow.core/NonEmptyList<#A> // arrow.core/NonEmptyCollection.distinctBy|distinctBy(kotlin.Function1<1:0,0:0>){0§}[0] @@ -59,6 +79,7 @@ abstract interface <#A: out kotlin/Any?> arrow.core/NonEmptyCollection : kotlin. open fun distinct(): arrow.core/NonEmptyList<#A> // arrow.core/NonEmptyCollection.distinct|distinct(){}[0] open fun firstOrNull(): #A // arrow.core/NonEmptyCollection.firstOrNull|firstOrNull(){}[0] open fun isEmpty(): kotlin/Boolean // arrow.core/NonEmptyCollection.isEmpty|isEmpty(){}[0] + open fun lastOrNull(): #A // arrow.core/NonEmptyCollection.lastOrNull|lastOrNull(){}[0] open fun toNonEmptyList(): arrow.core/NonEmptyList<#A> // arrow.core/NonEmptyCollection.toNonEmptyList|toNonEmptyList(){}[0] open fun toNonEmptySet(): arrow.core/NonEmptySet<#A> // arrow.core/NonEmptyCollection.toNonEmptySet|toNonEmptySet(){}[0] } @@ -369,8 +390,6 @@ final value class <#A: out kotlin/Any?> arrow.core/NonEmptyList : arrow.core/Non final val all // arrow.core/NonEmptyList.all|{}all[0] final fun (): kotlin.collections/List<#A> // arrow.core/NonEmptyList.all.|(){}[0] - final val head // arrow.core/NonEmptyList.head|{}head[0] - final fun (): #A // arrow.core/NonEmptyList.head.|(){}[0] final val size // arrow.core/NonEmptyList.size|{}size[0] final fun (): kotlin/Int // arrow.core/NonEmptyList.size.|(){}[0] final val tail // arrow.core/NonEmptyList.tail|{}tail[0] @@ -389,7 +408,6 @@ final value class <#A: out kotlin/Any?> arrow.core/NonEmptyList : arrow.core/Non final fun isEmpty(): kotlin/Boolean // arrow.core/NonEmptyList.isEmpty|isEmpty(){}[0] final fun iterator(): kotlin.collections/Iterator<#A> // arrow.core/NonEmptyList.iterator|iterator(){}[0] final fun lastIndexOf(#A): kotlin/Int // arrow.core/NonEmptyList.lastIndexOf|lastIndexOf(1:0){}[0] - final fun lastOrNull(): #A // arrow.core/NonEmptyList.lastOrNull|lastOrNull(){}[0] final fun listIterator(): kotlin.collections/ListIterator<#A> // arrow.core/NonEmptyList.listIterator|listIterator(){}[0] final fun listIterator(kotlin/Int): kotlin.collections/ListIterator<#A> // arrow.core/NonEmptyList.listIterator|listIterator(kotlin.Int){}[0] final fun plus(#A): arrow.core/NonEmptyList<#A> // arrow.core/NonEmptyList.plus|plus(1:0){}[0] @@ -414,7 +432,6 @@ final value class <#A: out kotlin/Any?> arrow.core/NonEmptyList : arrow.core/Non final inline fun <#A1: kotlin/Any?> foldLeft(#A1, kotlin/Function2<#A1, #A, #A1>): #A1 // arrow.core/NonEmptyList.foldLeft|foldLeft(0:0;kotlin.Function2<0:0,1:0,0:0>){0§}[0] final inline fun <#A1: kotlin/Any?> map(kotlin/Function1<#A, #A1>): arrow.core/NonEmptyList<#A1> // arrow.core/NonEmptyList.map|map(kotlin.Function1<1:0,0:0>){0§}[0] final inline fun <#A1: kotlin/Any?> mapIndexed(kotlin/Function2): arrow.core/NonEmptyList<#A1> // arrow.core/NonEmptyList.mapIndexed|mapIndexed(kotlin.Function2){0§}[0] - final inline fun distinct(): arrow.core/NonEmptyList<#A> // arrow.core/NonEmptyList.distinct|distinct(){}[0] final object Companion { // arrow.core/NonEmptyList.Companion|null[0] final val unit // arrow.core/NonEmptyList.Companion.unit|{}unit[0] @@ -433,8 +450,6 @@ final value class <#A: out kotlin/Any?> arrow.core/NonEmptySet : arrow.core/NonE final val elements // arrow.core/NonEmptySet.elements|{}elements[0] final fun (): kotlin.collections/Set<#A> // arrow.core/NonEmptySet.elements.|(){}[0] - final val head // arrow.core/NonEmptySet.head|{}head[0] - final fun (): #A // arrow.core/NonEmptySet.head.|(){}[0] final val size // arrow.core/NonEmptySet.size|{}size[0] final fun (): kotlin/Int // arrow.core/NonEmptySet.size.|(){}[0] @@ -450,7 +465,6 @@ final value class <#A: out kotlin/Any?> arrow.core/NonEmptySet : arrow.core/NonE final fun hashCode(): kotlin/Int // arrow.core/NonEmptySet.hashCode|hashCode(){}[0] final fun isEmpty(): kotlin/Boolean // arrow.core/NonEmptySet.isEmpty|isEmpty(){}[0] final fun iterator(): kotlin.collections/Iterator<#A> // arrow.core/NonEmptySet.iterator|iterator(){}[0] - final fun lastOrNull(): #A // arrow.core/NonEmptySet.lastOrNull|lastOrNull(){}[0] final fun plus(#A): arrow.core/NonEmptySet<#A> // arrow.core/NonEmptySet.plus|plus(1:0){}[0] final fun plus(kotlin.collections/Iterable<#A>): arrow.core/NonEmptySet<#A> // arrow.core/NonEmptySet.plus|plus(kotlin.collections.Iterable<1:0>){}[0] final fun toSet(): kotlin.collections/Set<#A> // arrow.core/NonEmptySet.toSet|toSet(){}[0] @@ -724,6 +738,8 @@ final const val arrow.core/RedundantAPI // arrow.core/RedundantAPI|{}RedundantAP final fun (arrow.core.raise/Traced).arrow.core.raise/withCause(arrow.core.raise/Traced): arrow.core.raise/Traced // arrow.core.raise/withCause|withCause@arrow.core.raise.Traced(arrow.core.raise.Traced){}[0] final fun (kotlin/String).arrow.core/escaped(): kotlin/String // arrow.core/escaped|escaped@kotlin.String(){}[0] final fun <#A: kotlin/Any> (kotlin/Function1<#A, kotlin/Boolean>).arrow.core/mapNullable(): kotlin/Function1<#A?, kotlin/Boolean> // arrow.core/mapNullable|mapNullable@kotlin.Function1<0:0,kotlin.Boolean>(){0§}[0] +final fun <#A: kotlin/Any?, #B: arrow.core/MonotoneCollectionBuilder.NonEmpty & kotlin.collections/List<#A>> (#B).arrow.core/asNonEmptyList(): arrow.core/NonEmptyList<#A> // arrow.core/asNonEmptyList|asNonEmptyList@0:1(){0§;1§&arrow.core.MonotoneCollectionBuilder.NonEmpty>}[0] +final fun <#A: kotlin/Any?, #B: arrow.core/MonotoneCollectionBuilder.NonEmpty & kotlin.collections/Set<#A>> (#B).arrow.core/asNonEmptySet(): arrow.core/NonEmptySet<#A> // arrow.core/asNonEmptySet|asNonEmptySet@0:1(){0§;1§&arrow.core.MonotoneCollectionBuilder.NonEmpty>}[0] final fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?, #D: kotlin/Any?, #E: kotlin/Any?, #F: kotlin/Any?, #G: kotlin/Any?, #H: kotlin/Any?, #I: kotlin/Any?, #J: kotlin/Any?, #K: kotlin/Any?> (kotlin.sequences/Sequence<#A>).arrow.core/zip(kotlin.sequences/Sequence<#B>, kotlin.sequences/Sequence<#C>, kotlin.sequences/Sequence<#D>, kotlin.sequences/Sequence<#E>, kotlin.sequences/Sequence<#F>, kotlin.sequences/Sequence<#G>, kotlin.sequences/Sequence<#H>, kotlin.sequences/Sequence<#I>, kotlin.sequences/Sequence<#J>, kotlin/Function10<#A, #B, #C, #D, #E, #F, #G, #H, #I, #J, #K>): kotlin.sequences/Sequence<#K> // arrow.core/zip|zip@kotlin.sequences.Sequence<0:0>(kotlin.sequences.Sequence<0:1>;kotlin.sequences.Sequence<0:2>;kotlin.sequences.Sequence<0:3>;kotlin.sequences.Sequence<0:4>;kotlin.sequences.Sequence<0:5>;kotlin.sequences.Sequence<0:6>;kotlin.sequences.Sequence<0:7>;kotlin.sequences.Sequence<0:8>;kotlin.sequences.Sequence<0:9>;kotlin.Function10<0:0,0:1,0:2,0:3,0:4,0:5,0:6,0:7,0:8,0:9,0:10>){0§;1§;2§;3§;4§;5§;6§;7§;8§;9§;10§}[0] final fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?, #D: kotlin/Any?, #E: kotlin/Any?, #F: kotlin/Any?, #G: kotlin/Any?, #H: kotlin/Any?, #I: kotlin/Any?, #J: kotlin/Any?> (kotlin.sequences/Sequence<#A>).arrow.core/zip(kotlin.sequences/Sequence<#B>, kotlin.sequences/Sequence<#C>, kotlin.sequences/Sequence<#D>, kotlin.sequences/Sequence<#E>, kotlin.sequences/Sequence<#F>, kotlin.sequences/Sequence<#G>, kotlin.sequences/Sequence<#H>, kotlin.sequences/Sequence<#I>, kotlin/Function9<#A, #B, #C, #D, #E, #F, #G, #H, #I, #J>): kotlin.sequences/Sequence<#J> // arrow.core/zip|zip@kotlin.sequences.Sequence<0:0>(kotlin.sequences.Sequence<0:1>;kotlin.sequences.Sequence<0:2>;kotlin.sequences.Sequence<0:3>;kotlin.sequences.Sequence<0:4>;kotlin.sequences.Sequence<0:5>;kotlin.sequences.Sequence<0:6>;kotlin.sequences.Sequence<0:7>;kotlin.sequences.Sequence<0:8>;kotlin.Function9<0:0,0:1,0:2,0:3,0:4,0:5,0:6,0:7,0:8,0:9>){0§;1§;2§;3§;4§;5§;6§;7§;8§;9§}[0] final fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?, #D: kotlin/Any?, #E: kotlin/Any?, #F: kotlin/Any?, #G: kotlin/Any?, #H: kotlin/Any?, #I: kotlin/Any?> (arrow.core/Tuple8<#A, #B, #C, #D, #E, #F, #G, #H>).arrow.core/plus(#I): arrow.core/Tuple9<#A, #B, #C, #D, #E, #F, #G, #H, #I> // arrow.core/plus|plus@arrow.core.Tuple8<0:0,0:1,0:2,0:3,0:4,0:5,0:6,0:7>(0:8){0§;1§;2§;3§;4§;5§;6§;7§;8§}[0] @@ -828,6 +844,10 @@ final fun <#A: kotlin/Any?> (#A).arrow.core/some(): arrow.core/Option<#A> // arr final fun <#A: kotlin/Any?> (#A?).arrow.core/toOption(): arrow.core/Option<#A> // arrow.core/toOption|toOption@0:0?(){0§}[0] final fun <#A: kotlin/Any?> (arrow.core.raise/Accumulate<#A>).arrow.core.raise/tolerant(arrow.core.raise/Raise>): arrow.core.raise/Accumulate<#A> // arrow.core.raise/tolerant|tolerant@arrow.core.raise.Accumulate<0:0>(arrow.core.raise.Raise>){0§}[0] final fun <#A: kotlin/Any?> (arrow.core/Either<#A, #A>).arrow.core/merge(): #A // arrow.core/merge|merge@arrow.core.Either<0:0,0:0>(){0§}[0] +final fun <#A: kotlin/Any?> (arrow.core/MonotoneCollectionBuilder<#A>).arrow.core/add(#A) // arrow.core/add|add@arrow.core.MonotoneCollectionBuilder<0:0>(0:0){0§}[0] +final fun <#A: kotlin/Any?> (arrow.core/MonotoneCollectionBuilder<#A>).arrow.core/addAll(arrow.core/NonEmptyCollection<#A>) // arrow.core/addAll|addAll@arrow.core.MonotoneCollectionBuilder<0:0>(arrow.core.NonEmptyCollection<0:0>){0§}[0] +final fun <#A: kotlin/Any?> (arrow.core/MonotoneCollectionBuilder<#A>).arrow.core/addAll(kotlin.collections/Collection<#A>) // arrow.core/addAll|addAll@arrow.core.MonotoneCollectionBuilder<0:0>(kotlin.collections.Collection<0:0>){0§}[0] +final fun <#A: kotlin/Any?> (arrow.core/MonotoneCollectionBuilder<#A>).arrow.core/addAll(kotlin.collections/Iterable<#A>) // arrow.core/addAll|addAll@arrow.core.MonotoneCollectionBuilder<0:0>(kotlin.collections.Iterable<0:0>){0§}[0] final fun <#A: kotlin/Any?> (arrow.core/NonEmptyList>).arrow.core/flatten(): arrow.core/NonEmptyList<#A> // arrow.core/flatten|flatten@arrow.core.NonEmptyList>(){0§}[0] final fun <#A: kotlin/Any?> (arrow.core/Option>).arrow.core/flatten(): arrow.core/Option<#A> // arrow.core/flatten|flatten@arrow.core.Option>(){0§}[0] final fun <#A: kotlin/Any?> (context(arrow.core.raise/Raise<#A>)).arrow.core.raise.context/raise(#A): kotlin/Nothing // arrow.core.raise.context/raise|raise(arrow.core.raise.Raise<0:0>)(0:0){0§}[0] @@ -905,6 +925,10 @@ final fun arrow.core/sort(kotlin/Long, kotlin/LongArray...): kotlin.collections/ final fun arrow.core/sort(kotlin/Short, kotlin/Short): kotlin/Pair // arrow.core/sort|sort(kotlin.Short;kotlin.Short){}[0] final fun arrow.core/sort(kotlin/Short, kotlin/Short, kotlin/Short): kotlin/Triple // arrow.core/sort|sort(kotlin.Short;kotlin.Short;kotlin.Short){}[0] final fun arrow.core/sort(kotlin/Short, kotlin/ShortArray...): kotlin.collections/List // arrow.core/sort|sort(kotlin.Short;kotlin.ShortArray...){}[0] +final inline fun <#A: kotlin/Any?, #B: arrow.core/MonotoneCollectionBuilder.NonEmpty & kotlin.collections/List<#A>> arrow.core/buildNonEmptyList(kotlin/Function1, #B>): arrow.core/NonEmptyList<#A> // arrow.core/buildNonEmptyList|buildNonEmptyList(kotlin.Function1,0:1>){0§;1§&arrow.core.MonotoneCollectionBuilder.NonEmpty>}[0] +final inline fun <#A: kotlin/Any?, #B: arrow.core/MonotoneCollectionBuilder.NonEmpty & kotlin.collections/List<#A>> arrow.core/buildNonEmptyList(kotlin/Int, kotlin/Function1, #B>): arrow.core/NonEmptyList<#A> // arrow.core/buildNonEmptyList|buildNonEmptyList(kotlin.Int;kotlin.Function1,0:1>){0§;1§&arrow.core.MonotoneCollectionBuilder.NonEmpty>}[0] +final inline fun <#A: kotlin/Any?, #B: arrow.core/MonotoneCollectionBuilder.NonEmpty & kotlin.collections/Set<#A>> arrow.core/buildNonEmptySet(kotlin/Function1, #B>): arrow.core/NonEmptySet<#A> // arrow.core/buildNonEmptySet|buildNonEmptySet(kotlin.Function1,0:1>){0§;1§&arrow.core.MonotoneCollectionBuilder.NonEmpty>}[0] +final inline fun <#A: kotlin/Any?, #B: arrow.core/MonotoneCollectionBuilder.NonEmpty & kotlin.collections/Set<#A>> arrow.core/buildNonEmptySet(kotlin/Int, kotlin/Function1, #B>): arrow.core/NonEmptySet<#A> // arrow.core/buildNonEmptySet|buildNonEmptySet(kotlin.Int;kotlin.Function1,0:1>){0§;1§&arrow.core.MonotoneCollectionBuilder.NonEmpty>}[0] final inline fun <#A: kotlin/Any?, #B: kotlin/Any> (arrow.core.raise/Raise<#A>).arrow.core.raise/ensureNotNull(#B?, kotlin/Function0<#A>): #B // arrow.core.raise/ensureNotNull|ensureNotNull@arrow.core.raise.Raise<0:0>(0:1?;kotlin.Function0<0:0>){0§;1§}[0] final inline fun <#A: kotlin/Any?, #B: kotlin/Any> (context(arrow.core.raise/Raise<#A>)).arrow.core.raise.context/ensureNotNull(#B?, kotlin/Function0<#A>): #B // arrow.core.raise.context/ensureNotNull|ensureNotNull(arrow.core.raise.Raise<0:0>)(0:1?;kotlin.Function0<0:0>){0§;1§}[0] final inline fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?, #D: kotlin/Any?, #E: kotlin/Any?, #F: kotlin/Any?, #G: kotlin/Any?, #H: kotlin/Any?, #I: kotlin/Any?, #J: kotlin/Any?, #K: kotlin/Any?, #L: kotlin/Any?> (kotlin.collections/Map<#A, #B>).arrow.core/zip(kotlin.collections/Map<#A, #C>, kotlin.collections/Map<#A, #D>, kotlin.collections/Map<#A, #E>, kotlin.collections/Map<#A, #F>, kotlin.collections/Map<#A, #G>, kotlin.collections/Map<#A, #H>, kotlin.collections/Map<#A, #I>, kotlin.collections/Map<#A, #J>, kotlin.collections/Map<#A, #K>, kotlin/Function11<#A, #B, #C, #D, #E, #F, #G, #H, #I, #J, #K, #L>): kotlin.collections/Map<#A, #L> // arrow.core/zip|zip@kotlin.collections.Map<0:0,0:1>(kotlin.collections.Map<0:0,0:2>;kotlin.collections.Map<0:0,0:3>;kotlin.collections.Map<0:0,0:4>;kotlin.collections.Map<0:0,0:5>;kotlin.collections.Map<0:0,0:6>;kotlin.collections.Map<0:0,0:7>;kotlin.collections.Map<0:0,0:8>;kotlin.collections.Map<0:0,0:9>;kotlin.collections.Map<0:0,0:10>;kotlin.Function11<0:0,0:1,0:2,0:3,0:4,0:5,0:6,0:7,0:8,0:9,0:10,0:11>){0§;1§;2§;3§;4§;5§;6§;7§;8§;9§;10§;11§}[0] diff --git a/arrow-libs/core/arrow-core/api/jvm/arrow-core.api b/arrow-libs/core/arrow-core/api/jvm/arrow-core.api index 4f419e93f2..7cad018a18 100644 --- a/arrow-libs/core/arrow-core/api/jvm/arrow-core.api +++ b/arrow-libs/core/arrow-core/api/jvm/arrow-core.api @@ -349,6 +349,45 @@ public final class arrow/core/MemoizedDeepRecursiveFunctionKt { public static synthetic fun MemoizedDeepRecursiveFunction$default (Larrow/core/MemoizationCache;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlin/DeepRecursiveFunction; } +public abstract interface class arrow/core/MonotoneCollectionBuilder { + public abstract fun _add (Ljava/lang/Object;)V + public abstract fun _addAll (Ljava/util/Collection;)V +} + +public abstract interface class arrow/core/MonotoneCollectionBuilder$NonEmpty { +} + +public final class arrow/core/MonotoneCollectionBuilderKt { + public static final fun add (Larrow/core/MonotoneCollectionBuilder;Ljava/lang/Object;)V + public static final fun addAll (Larrow/core/MonotoneCollectionBuilder;Larrow/core/NonEmptyCollection;)V + public static final fun addAll (Larrow/core/MonotoneCollectionBuilder;Ljava/lang/Iterable;)V + public static final fun addAll (Larrow/core/MonotoneCollectionBuilder;Ljava/util/Collection;)V + public static final fun asNonEmptyList (Ljava/util/List;)Ljava/util/List; + public static final fun asNonEmptySet (Ljava/util/Set;)Ljava/util/Set; + public static final fun buildNonEmptyList (ILkotlin/jvm/functions/Function1;)Ljava/util/List; + public static final fun buildNonEmptyList (Lkotlin/jvm/functions/Function1;)Ljava/util/List; + public static final fun buildNonEmptySet (ILkotlin/jvm/functions/Function1;)Ljava/util/Set; + public static final fun buildNonEmptySet (Lkotlin/jvm/functions/Function1;)Ljava/util/Set; +} + +public abstract interface class arrow/core/MonotoneMutableList : arrow/core/MonotoneCollectionBuilder, java/util/List, kotlin/jvm/internal/markers/KMappedMarker { + public static final field Companion Larrow/core/MonotoneMutableList$Companion; +} + +public final class arrow/core/MonotoneMutableList$Companion { + public final fun invoke ()Larrow/core/MonotoneMutableList; + public final fun invoke (I)Larrow/core/MonotoneMutableList; +} + +public abstract interface class arrow/core/MonotoneMutableSet : arrow/core/MonotoneCollectionBuilder, java/util/Set, kotlin/jvm/internal/markers/KMappedMarker { + public static final field Companion Larrow/core/MonotoneMutableSet$Companion; +} + +public final class arrow/core/MonotoneMutableSet$Companion { + public final fun invoke ()Larrow/core/MonotoneMutableSet; + public final fun invoke (I)Larrow/core/MonotoneMutableSet; +} + public abstract interface class arrow/core/NonEmptyCollection : java/util/Collection, kotlin/jvm/internal/markers/KMappedMarker { public abstract fun distinct-1X0FA-Y ()Ljava/util/List; public abstract fun distinctBy-0-xjo5U (Lkotlin/jvm/functions/Function1;)Ljava/util/List; @@ -371,7 +410,9 @@ public final class arrow/core/NonEmptyCollection$DefaultImpls { public static fun distinctBy-0-xjo5U (Larrow/core/NonEmptyCollection;Lkotlin/jvm/functions/Function1;)Ljava/util/List; public static fun firstOrNull (Larrow/core/NonEmptyCollection;)Ljava/lang/Object; public static fun flatMap-0-xjo5U (Larrow/core/NonEmptyCollection;Lkotlin/jvm/functions/Function1;)Ljava/util/List; + public static fun getHead (Larrow/core/NonEmptyCollection;)Ljava/lang/Object; public static fun isEmpty (Larrow/core/NonEmptyCollection;)Z + public static fun lastOrNull (Larrow/core/NonEmptyCollection;)Ljava/lang/Object; public static fun map-0-xjo5U (Larrow/core/NonEmptyCollection;Lkotlin/jvm/functions/Function1;)Ljava/util/List; public static fun mapIndexed-0-xjo5U (Larrow/core/NonEmptyCollection;Lkotlin/jvm/functions/Function2;)Ljava/util/List; public static fun toNonEmptyList-1X0FA-Y (Larrow/core/NonEmptyCollection;)Ljava/util/List; diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/MonotoneCollectionBuilder.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/MonotoneCollectionBuilder.kt new file mode 100644 index 0000000000..12f5e31434 --- /dev/null +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/MonotoneCollectionBuilder.kt @@ -0,0 +1,128 @@ +@file:Suppress("API_NOT_AVAILABLE") +@file:OptIn(ExperimentalContracts::class) +package arrow.core + +import arrow.core.MonotoneCollectionBuilder.NonEmpty +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + +/** + * A builder for collections that can only grow by adding elements. + * Removing elements is not supported to preserve monotonicity. + */ +@SubclassOptInRequired(PotentiallyUnsafeNonEmptyOperation::class) +public interface MonotoneCollectionBuilder { + // underscored so that addAll(Nec) extension overload takes precedence + // Turning this into an abstract class doesn't work well because of KT-83602 + public fun _addAll(elements: Collection) + + public fun _add(element: E) + + /** + * Marker interface for builders that guarantee at least one element has been added. + * @see MonotoneCollectionBuilder + * @see buildNonEmptyList + */ + public interface NonEmpty +} + +public fun MonotoneCollectionBuilder.add(element: E) { + contract { returns() implies (this@add is NonEmpty) } + return _add(element) +} + +public fun MonotoneCollectionBuilder.addAll(elements: Iterable): Unit = when (elements) { + is Collection -> addAll(elements) + else -> for (item in elements) add(item) +} + +public fun MonotoneCollectionBuilder.addAll(elements: NonEmptyCollection) { + contract { returns() implies (this@addAll is NonEmpty) } + _addAll(elements) +} + +public fun MonotoneCollectionBuilder.addAll(elements: Collection): Unit = _addAll(elements) + +@SubclassOptInRequired(PotentiallyUnsafeNonEmptyOperation::class) +private abstract class MonotoneMutableCollectionImpl(private val underlying: MutableCollection) : MonotoneCollectionBuilder, NonEmpty { + final override fun _addAll(elements: Collection) { underlying.addAll(elements) } + final override fun _add(element: E) { underlying.add(element) } + + final override fun equals(other: Any?) = underlying == other + final override fun hashCode() = underlying.hashCode() + final override fun toString() = underlying.toString() +} + +/** + * A mutable list that can only grow by adding elements. + * Removing elements is not supported to preserve monotonicity. + */ +@SubclassOptInRequired(PotentiallyUnsafeNonEmptyOperation::class) +public interface MonotoneMutableList: MonotoneCollectionBuilder, List { + public companion object { + public operator fun invoke(): MonotoneMutableList = Impl() + + public operator fun invoke(initialCapacity: Int): MonotoneMutableList = Impl(initialCapacity) + } + + @OptIn(PotentiallyUnsafeNonEmptyOperation::class) + private class Impl private constructor(underlying: MutableList) : MonotoneMutableCollectionImpl(underlying), MonotoneMutableList, List by underlying { + constructor() : this(ArrayList()) + constructor(initialCapacity: Int) : this(ArrayList(initialCapacity)) + } +} + +@OptIn(PotentiallyUnsafeNonEmptyOperation::class) +public fun L.asNonEmptyList(): NonEmptyList where L : List, L : NonEmpty = NonEmptyList(this) + +public inline fun buildNonEmptyList( + builderAction: MonotoneMutableList.() -> L +): NonEmptyList where L : List, L : NonEmpty { + contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) } + return builderAction(MonotoneMutableList()).asNonEmptyList() +} + +public inline fun buildNonEmptyList( + capacity: Int, + builderAction: MonotoneMutableList.() -> L +): NonEmptyList where L : List, L : NonEmpty { + contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) } + return builderAction(MonotoneMutableList(capacity)).asNonEmptyList() +} + +/** + * A mutable list that can only grow by adding elements. + * Removing elements is not supported to preserve monotonicity. + */ +@SubclassOptInRequired(PotentiallyUnsafeNonEmptyOperation::class) +public interface MonotoneMutableSet: MonotoneCollectionBuilder, Set { + public companion object { + public operator fun invoke(): MonotoneMutableSet = Impl() + public operator fun invoke(initialCapacity: Int): MonotoneMutableSet = Impl(initialCapacity) + } + + @OptIn(PotentiallyUnsafeNonEmptyOperation::class) + private class Impl private constructor(underlying: MutableSet) : MonotoneMutableCollectionImpl(underlying), MonotoneMutableSet, NonEmpty, Set by underlying { + constructor() : this(LinkedHashSet()) + constructor(initialCapacity: Int) : this(LinkedHashSet(initialCapacity)) + } +} + +@OptIn(PotentiallyUnsafeNonEmptyOperation::class) +public fun S.asNonEmptySet(): NonEmptySet where S : Set, S : NonEmpty = NonEmptySet(this) + +public inline fun buildNonEmptySet( + builderAction: MonotoneMutableSet.() -> S +): NonEmptySet where S : Set, S : NonEmpty { + contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) } + return builderAction(MonotoneMutableSet()).asNonEmptySet() +} + +public inline fun buildNonEmptySet( + capacity: Int, + builderAction: MonotoneMutableSet.() -> S +): NonEmptySet where S : Set, S : NonEmpty { + contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) } + return builderAction(MonotoneMutableSet(capacity)).asNonEmptySet() +} diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptyCollection.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptyCollection.kt index c53acfa70a..f5a3db4dbf 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptyCollection.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptyCollection.kt @@ -4,42 +4,64 @@ package arrow.core * Common interface for collections that always have * at least one element (available from [head]). */ +@SubclassOptInRequired(PotentiallyUnsafeNonEmptyOperation::class) public interface NonEmptyCollection : Collection { override fun isEmpty(): Boolean = false - public val head: E + public val head: E get() = first() public operator fun plus(element: @UnsafeVariance E): NonEmptyCollection + public operator fun plus(elements: Iterable<@UnsafeVariance E>): NonEmptyCollection - public fun toNonEmptySet(): NonEmptySet = toNonEmptySetOrThrow() - public fun toNonEmptyList(): NonEmptyList = toNonEmptyListOrThrow() + public fun toNonEmptySet(): NonEmptySet = buildNonEmptySet(size) { + addAll(this@NonEmptyCollection) + this + } + + public fun toNonEmptyList(): NonEmptyList = buildNonEmptyList(size) { + addAll(this@NonEmptyCollection) + this + } // These functions take precedence over the extensions in [Collection]. // This way non-emptiness is tracked by the type system. public fun firstOrNull(): E = head - public fun lastOrNull(): E - - public fun distinct(): NonEmptyList = - delegate { it.distinct() } - public fun distinctBy(selector: (E) -> K): NonEmptyList = - delegate { it.distinctBy(selector) } - public fun flatMap(transform: (E) -> NonEmptyCollection): NonEmptyList = - delegate { it.flatMap(transform) } - public fun map(transform: (E) -> T): NonEmptyList = - delegate { it.map(transform) } - public fun mapIndexed(transform: (index:Int, E) -> T): NonEmptyList = - delegate { it.mapIndexed(transform) } - public fun zip(other: NonEmptyCollection): NonEmptyCollection> = - delegate { it.zip(other) } - - /** - * Convenience method which delegates the implementation to [Collection], - * and wraps the resulting [List] as a non-empty one. - */ - @OptIn(PotentiallyUnsafeNonEmptyOperation::class) - private inline fun delegate(crossinline f: (Collection) -> List): NonEmptyList = - f(this as Collection).wrapAsNonEmptyListOrThrow() + public fun lastOrNull(): E = last() + + public fun distinct(): NonEmptyList = toNonEmptySet().toNonEmptyList() + public fun distinctBy(selector: (E) -> K): NonEmptyList = buildNonEmptyList(size) { + add(head) // head is always distinct + val seen = hashSetOf() + var isFirst = true + for (e in this@NonEmptyCollection) { + if (seen.add(selector(e)) && !isFirst) add(e) + isFirst = false + } + this + } + public fun flatMap(transform: (E) -> NonEmptyCollection): NonEmptyList = buildNonEmptyList(size) { + val iterator = this@NonEmptyCollection.iterator() + do addAll(transform(iterator.next())) while (iterator.hasNext()) + this + } + public fun map(transform: (E) -> T): NonEmptyList = buildNonEmptyList(size) { + val iterator = this@NonEmptyCollection.iterator() + do add(transform(iterator.next())) while (iterator.hasNext()) + this + } + public fun mapIndexed(transform: (index:Int, E) -> T): NonEmptyList = buildNonEmptyList(size) { + var i = 0 + val iterator = this@NonEmptyCollection.iterator() + do add(transform(i++, iterator.next())) while (iterator.hasNext()) + this + } + public fun zip(other: NonEmptyCollection): NonEmptyCollection> = buildNonEmptyList(minOf(size, other.size)) { + val first = this@NonEmptyCollection.iterator() + val second = other.iterator() + do add(first.next() to second.next()) while (first.hasNext() && second.hasNext()) + this + } } /** @@ -48,5 +70,5 @@ public interface NonEmptyCollection : Collection { */ @RequiresOptIn @Retention(AnnotationRetention.BINARY) -@Target(AnnotationTarget.FUNCTION) +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR) public annotation class PotentiallyUnsafeNonEmptyOperation diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptyList.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptyList.kt index 513d70b31a..34ac204595 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptyList.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptyList.kt @@ -3,7 +3,13 @@ package arrow.core +import arrow.core.Ior.Left +import arrow.core.Ior.Right +import arrow.core.Ior.Both import arrow.core.raise.RaiseAccumulate +import arrow.core.raise.either +import arrow.core.raise.mapOrAccumulate +import arrow.core.raise.withError import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -154,12 +160,17 @@ public typealias Nel = NonEmptyList * - `a.zip(b, c) { ... }` can be used to compute over multiple `NonEmptyList` values preserving type information and __abstracting over arity__ with `zip` * */ +@OptIn(PotentiallyUnsafeNonEmptyOperation::class) @JvmInline -public value class NonEmptyList @PublishedApi internal constructor( +public value class NonEmptyList @PotentiallyUnsafeNonEmptyOperation @PublishedApi internal constructor( public val all: List ) : List by all, NonEmptyCollection { - public constructor(head: E, tail: List): this(listOf(head) + tail) + public constructor(head: E, tail: List): this(buildNonEmptyList(tail.size + 1) { + add(head) + addAll(tail) + this + }.all) override fun equals(other: Any?): Boolean = when (other) { is NonEmptyList<*> -> this.all == other.all @@ -173,57 +184,79 @@ public value class NonEmptyList @PublishedApi internal constructor( @JvmExposeBoxed @Suppress("USELESS_JVM_EXPOSE_BOXED") public fun toList(): List = all - public override val head: E - get() = all.first() - public val tail: List get() = all.subList(1, all.size) - override fun lastOrNull(): E = all.last() - - @Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") - public override inline fun distinct(): NonEmptyList = - NonEmptyList(all.distinct()) - @Suppress("OVERRIDE_BY_INLINE") - public override inline fun distinctBy(selector: (E) -> K): NonEmptyList = - NonEmptyList(all.distinctBy(selector)) + public override inline fun distinctBy(selector: (E) -> K): NonEmptyList = buildNonEmptyList(size) { + add(head) // head is always distinct + val seen = hashSetOf() + var isFirst = true + for (e in all) { + if (seen.add(selector(e)) && !isFirst) add(e) + isFirst = false + } + this + } + // These can be simplified by introducing some forEachNonEmpty extension, but we'd need + // "KT-83404 Smart casts don't propagate past scoping functions" fixed first. @Suppress("OVERRIDE_BY_INLINE") - public override inline fun map(transform: (E) -> T): NonEmptyList = - NonEmptyList(all.map(transform)) + public override inline fun map(transform: (E) -> T): NonEmptyList = buildNonEmptyList(size) { + val iterator = all.iterator() + do add(transform(iterator.next())) while (iterator.hasNext()) + this + } @Suppress("OVERRIDE_BY_INLINE") - public override inline fun flatMap(transform: (E) -> NonEmptyCollection): NonEmptyList = - NonEmptyList(all.flatMap(transform)) + public override inline fun flatMap(transform: (E) -> NonEmptyCollection): NonEmptyList = buildNonEmptyList(size) { + val iterator = all.iterator() + do addAll(transform(iterator.next())) while (iterator.hasNext()) + this + } @Suppress("OVERRIDE_BY_INLINE") - public override inline fun mapIndexed(transform: (index: Int, E) -> T): NonEmptyList = - NonEmptyList(all.mapIndexed(transform)) + public override inline fun mapIndexed(transform: (index: Int, E) -> T): NonEmptyList = buildNonEmptyList(size) { + val iterator = all.iterator() + var index = 0 + do add(transform(index++, iterator.next())) while (iterator.hasNext()) + this + } public operator fun plus(l: NonEmptyList<@UnsafeVariance E>): NonEmptyList = this + l.all - public override operator fun plus(elements: Iterable<@UnsafeVariance E>): NonEmptyList = - NonEmptyList(all + elements) + override fun plus(elements: Iterable<@UnsafeVariance E>): NonEmptyList = buildNonEmptyList(size + elements.collectionSizeOrDefault(10)) { + addAll(this@NonEmptyList) + addAll(elements) + this + } - public override operator fun plus(element: @UnsafeVariance E): NonEmptyList = - NonEmptyList(all + element) + override fun plus(element: @UnsafeVariance E): NonEmptyList = buildNonEmptyList(size + 1) { + addAll(this@NonEmptyList) + add(element) + this + } - @Suppress("WRONG_INVOCATION_KIND") public inline fun foldLeft(b: Acc, f: (Acc, E) -> Acc): Acc { contract { callsInPlace(f, InvocationKind.AT_LEAST_ONCE) } - return all.fold(b) { acc, e -> f(acc, e) } + var accumulator = b + val iterator = iterator() + do accumulator = f(accumulator, iterator.next()) while (iterator.hasNext()) + return accumulator } public inline fun coflatMap(f: (NonEmptyList) -> T): NonEmptyList { contract { callsInPlace(f, InvocationKind.AT_LEAST_ONCE) } - return buildList { + var current = this + return buildNonEmptyList(all.size + 1) { var i = 0 - // Inv: i < size - do add(f(NonEmptyList(all.subList(i, all.size)))) - while (++i < all.size) - }.let(::NonEmptyList) + do { + add(f(current)) + current = all.subList(++i, all.size).wrapAsNonEmptyListOrNull() ?: break + } while (true) + this + } } public fun extract(): E = @@ -232,15 +265,21 @@ public value class NonEmptyList @PublishedApi internal constructor( override fun toString(): String = all.toString() public fun align(other: NonEmptyList): NonEmptyList> = - NonEmptyList(all.align(other)) + padZip(other, ::Left, ::Right, ::Both) public fun padZip(other: NonEmptyList): NonEmptyList> = padZip(other, { it to null }, { null to it }, { a, b -> a to b }) - @Suppress("WRONG_INVOCATION_KIND") public inline fun padZip(other: NonEmptyList, left: (E) -> C, right: (B) -> C, both: (E, B) -> C): NonEmptyList { contract { callsInPlace(both, InvocationKind.AT_LEAST_ONCE) } - return all.padZip(other, left, right) { e, b -> both(e, b) }.let(::NonEmptyList) + val first = iterator() + val second = other.iterator() + return buildNonEmptyList(maxOf(size, other.size)) { + do add(both(first.next(), second.next())) while (first.hasNext() && second.hasNext()) + while (first.hasNext()) add(left(first.next())) + while (second.hasNext()) add(right(second.next())) + this + } } public companion object { @@ -260,26 +299,36 @@ public value class NonEmptyList @PublishedApi internal constructor( public fun zip(other: NonEmptyList): NonEmptyList> = zip(other, ::Pair) - @Suppress("WRONG_INVOCATION_KIND") public inline fun zip( b: NonEmptyList, map: (E, B) -> Z ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(b) { a, bb -> map(a, bb) }.let(::NonEmptyList) + val aa = iterator() + val bb = b.iterator() + return buildNonEmptyList(minOf(this.size, b.size)) { + do add(map(aa.next(), bb.next())) + while (aa.hasNext() && bb.hasNext()) + this + } } - @Suppress("WRONG_INVOCATION_KIND") public inline fun zip( b: NonEmptyList, c: NonEmptyList, map: (E, B, C) -> Z ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(b, c) { a, bb, cc -> map(a, bb, cc) }.let(::NonEmptyList) + val aa = iterator() + val bb = b.iterator() + val cc = c.iterator() + return buildNonEmptyList(minOf(this.size, b.size, c.size)) { + do add(map(aa.next(), bb.next(), cc.next())) + while (aa.hasNext() && bb.hasNext() && cc.hasNext()) + this + } } - @Suppress("WRONG_INVOCATION_KIND") public inline fun zip( b: NonEmptyList, c: NonEmptyList, @@ -287,10 +336,17 @@ public value class NonEmptyList @PublishedApi internal constructor( map: (E, B, C, D) -> Z ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(b, c, d) { a, bb, cc, dd -> map(a, bb, cc, dd) }.let(::NonEmptyList) + val aa = iterator() + val bb = b.iterator() + val cc = c.iterator() + val dd = d.iterator() + return buildNonEmptyList(minOf(this.size, b.size, c.size, d.size)) { + do add(map(aa.next(), bb.next(), cc.next(), dd.next())) + while (aa.hasNext() && bb.hasNext() && cc.hasNext() && dd.hasNext()) + this + } } - @Suppress("WRONG_INVOCATION_KIND") public inline fun zip( b: NonEmptyList, c: NonEmptyList, @@ -299,10 +355,18 @@ public value class NonEmptyList @PublishedApi internal constructor( map: (E, B, C, D, F) -> Z ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(b, c, d, e) { a, bb, cc, dd, ee -> map(a, bb, cc, dd, ee) }.let(::NonEmptyList) + val aa = iterator() + val bb = b.iterator() + val cc = c.iterator() + val dd = d.iterator() + val ee = e.iterator() + return buildNonEmptyList(minOf(this.size, b.size, c.size, d.size, e.size)) { + do add(map(aa.next(), bb.next(), cc.next(), dd.next(), ee.next())) + while (aa.hasNext() && bb.hasNext() && cc.hasNext() && dd.hasNext() && ee.hasNext()) + this + } } - @Suppress("WRONG_INVOCATION_KIND") public inline fun zip( b: NonEmptyList, c: NonEmptyList, @@ -312,10 +376,19 @@ public value class NonEmptyList @PublishedApi internal constructor( map: (E, B, C, D, F, G) -> Z ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(b, c, d, e, f) { a, bb, cc, dd, ee, ff -> map(a, bb, cc, dd, ee, ff) }.let(::NonEmptyList) + val aa = iterator() + val bb = b.iterator() + val cc = c.iterator() + val dd = d.iterator() + val ee = e.iterator() + val ff = f.iterator() + return buildNonEmptyList(minOf(this.size, b.size, c.size, d.size, e.size, f.size)) { + do add(map(aa.next(), bb.next(), cc.next(), dd.next(), ee.next(), ff.next())) + while (aa.hasNext() && bb.hasNext() && cc.hasNext() && dd.hasNext() && ee.hasNext() && ff.hasNext()) + this + } } - @Suppress("WRONG_INVOCATION_KIND") public inline fun zip( b: NonEmptyList, c: NonEmptyList, @@ -326,10 +399,20 @@ public value class NonEmptyList @PublishedApi internal constructor( map: (E, B, C, D, F, G, H) -> Z ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(b, c, d, e, f, g) { a, bb, cc, dd, ee, ff, gg -> map(a, bb, cc, dd, ee, ff, gg) }.let(::NonEmptyList) + val aa = iterator() + val bb = b.iterator() + val cc = c.iterator() + val dd = d.iterator() + val ee = e.iterator() + val ff = f.iterator() + val gg = g.iterator() + return buildNonEmptyList(minOf(this.size, b.size, c.size, d.size, e.size, f.size, g.size)) { + do add(map(aa.next(), bb.next(), cc.next(), dd.next(), ee.next(), ff.next(), gg.next())) + while (aa.hasNext() && bb.hasNext() && cc.hasNext() && dd.hasNext() && ee.hasNext() && ff.hasNext() && gg.hasNext()) + this + } } - @Suppress("WRONG_INVOCATION_KIND") public inline fun zip( b: NonEmptyList, c: NonEmptyList, @@ -341,10 +424,21 @@ public value class NonEmptyList @PublishedApi internal constructor( map: (E, B, C, D, F, G, H, I) -> Z ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(b, c, d, e, f, g, h) { a, bb, cc, dd, ee, ff, gg, hh -> map(a, bb, cc, dd, ee, ff, gg, hh) }.let(::NonEmptyList) + val aa = iterator() + val bb = b.iterator() + val cc = c.iterator() + val dd = d.iterator() + val ee = e.iterator() + val ff = f.iterator() + val gg = g.iterator() + val hh = h.iterator() + return buildNonEmptyList(minOf(this.size, b.size, c.size, d.size, e.size, f.size, g.size, h.size)) { + do add(map(aa.next(), bb.next(), cc.next(), dd.next(), ee.next(), ff.next(), gg.next(), hh.next())) + while (aa.hasNext() && bb.hasNext() && cc.hasNext() && dd.hasNext() && ee.hasNext() && ff.hasNext() && gg.hasNext() && hh.hasNext()) + this + } } - @Suppress("WRONG_INVOCATION_KIND") public inline fun zip( b: NonEmptyList, c: NonEmptyList, @@ -357,10 +451,22 @@ public value class NonEmptyList @PublishedApi internal constructor( map: (E, B, C, D, F, G, H, I, J) -> Z ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(b, c, d, e, f, g, h, i) { a, bb, cc, dd, ee, ff, gg, hh, ii -> map(a, bb, cc, dd, ee, ff, gg, hh, ii) }.let(::NonEmptyList) + val aa = iterator() + val bb = b.iterator() + val cc = c.iterator() + val dd = d.iterator() + val ee = e.iterator() + val ff = f.iterator() + val gg = g.iterator() + val hh = h.iterator() + val ii = i.iterator() + return buildNonEmptyList(minOf(this.size, b.size, c.size, d.size, e.size, f.size, g.size, h.size, i.size)) { + do add(map(aa.next(), bb.next(), cc.next(), dd.next(), ee.next(), ff.next(), gg.next(), hh.next(), ii.next())) + while (aa.hasNext() && bb.hasNext() && cc.hasNext() && dd.hasNext() && ee.hasNext() && ff.hasNext() && gg.hasNext() && hh.hasNext() && ii.hasNext()) + this + } } - @Suppress("WRONG_INVOCATION_KIND") public inline fun zip( b: NonEmptyList, c: NonEmptyList, @@ -374,18 +480,33 @@ public value class NonEmptyList @PublishedApi internal constructor( map: (E, B, C, D, F, G, H, I, J, K) -> Z ): NonEmptyList { contract { callsInPlace(map, InvocationKind.AT_LEAST_ONCE) } - return all.zip(b, c, d, e, f, g, h, i, j) { a, bb, cc, dd, ee, ff, gg, hh, ii, jj -> map(a, bb, cc, dd, ee, ff, gg, hh, ii, jj) }.let(::NonEmptyList) + val aa = iterator() + val bb = b.iterator() + val cc = c.iterator() + val dd = d.iterator() + val ee = e.iterator() + val ff = f.iterator() + val gg = g.iterator() + val hh = h.iterator() + val ii = i.iterator() + val jj = j.iterator() + return buildNonEmptyList(minOf(this.size, b.size, c.size, d.size, e.size, f.size, g.size, h.size, i.size, j.size)) { + do add(map(aa.next(), bb.next(), cc.next(), dd.next(), ee.next(), ff.next(), gg.next(), hh.next(), ii.next(), jj.next())) + while (aa.hasNext() && bb.hasNext() && cc.hasNext() && dd.hasNext() && ee.hasNext() && ff.hasNext() && gg.hasNext() && hh.hasNext() && ii.hasNext() && jj.hasNext()) + this + } } } @JvmName("nonEmptyListOf") -public fun nonEmptyListOf(head: E, vararg t: E): NonEmptyList = - NonEmptyList(listOf(head) + t) +public fun nonEmptyListOf(head: E, vararg t: E): NonEmptyList = NonEmptyList(head, t.asList()) @JvmName("nel") @Suppress("NOTHING_TO_INLINE") -public inline fun E.nel(): NonEmptyList = - NonEmptyList(listOf(this)) +public inline fun E.nel(): NonEmptyList = buildNonEmptyList(1) { + add(this@nel) + this +} public operator fun > NonEmptyList.compareTo(other: NonEmptyList): Int = all.compareTo(other.all) @@ -410,38 +531,41 @@ public inline fun > NonEmptyList.max(): E = public fun NonEmptyList>.unzip(): Pair, NonEmptyList> = this.unzip(::identity) -@Suppress("WRONG_INVOCATION_KIND") public inline fun NonEmptyList.unzip(f: (E) -> Pair): Pair, NonEmptyList> { contract { callsInPlace(f, InvocationKind.AT_LEAST_ONCE) } - val size = this.size - val listA = ArrayList(size) - val listB = ArrayList(size) - for (element in this) { - val (a, b) = f(element) + val size = size + val listA = MonotoneMutableList(size) + val listB = MonotoneMutableList(size) + val iterator = iterator() + do { + val (a, b) = f(iterator.next()) listA.add(a) listB.add(b) - } - return NonEmptyList(listA) to NonEmptyList(listB) + } while (iterator.hasNext()) + return listA.asNonEmptyList() to listB.asNonEmptyList() } public inline fun NonEmptyList.mapOrAccumulate( combine: (Error, Error) -> Error, @BuilderInference transform: RaiseAccumulate.(E) -> T -): Either> = - all.mapOrAccumulate(combine, transform).map(::NonEmptyList) +): Either> = either { + withError({ it.reduce(combine) }) { + mapOrAccumulate(this@mapOrAccumulate, transform) + } +} public inline fun NonEmptyList.mapOrAccumulate( @BuilderInference transform: RaiseAccumulate.(E) -> T -): Either, NonEmptyList> = - all.mapOrAccumulate(transform).map(::NonEmptyList) +): Either, NonEmptyList> = either { + mapOrAccumulate(this@mapOrAccumulate, transform) +} /** * Returns a [NonEmptyList] that contains a **copy** of the elements in [this]. */ @OptIn(PotentiallyUnsafeNonEmptyOperation::class) @JvmName("toNonEmptyListOrNull") -public fun Iterable.toNonEmptyListOrNull(): NonEmptyList? = - toList().wrapAsNonEmptyListOrNull() +public fun Iterable.toNonEmptyListOrNull(): NonEmptyList? = toList().wrapAsNonEmptyListOrNull() /** * Returns a [NonEmptyList] that contains a **copy** of the elements in [this]. @@ -453,10 +577,8 @@ public fun Iterable.toNonEmptyListOrNone(): Option> = /** * Returns a [NonEmptyList] that contains a **copy** of the elements in [this]. */ -@OptIn(PotentiallyUnsafeNonEmptyOperation::class) @JvmName("toNonEmptyListOrThrow") -public fun Iterable.toNonEmptyListOrThrow(): NonEmptyList = - toList().wrapAsNonEmptyListOrThrow() +public fun Iterable.toNonEmptyListOrThrow(): NonEmptyList = toNonEmptyListOrNull() ?: throw IllegalArgumentException("Cannot create NonEmptyList from empty Iterable") /** * Returns a [NonEmptyList] that wraps the given [this], avoiding an additional copy. @@ -465,11 +587,7 @@ public fun Iterable.toNonEmptyListOrThrow(): NonEmptyList = * You are responsible for keeping the non-emptiness invariant at all times. */ @PotentiallyUnsafeNonEmptyOperation -public fun List.wrapAsNonEmptyListOrThrow(): NonEmptyList { - require(isNotEmpty()) - return NonEmptyList(this) -} - +public fun List.wrapAsNonEmptyListOrThrow(): NonEmptyList = wrapAsNonEmptyListOrNull() ?: throw IllegalArgumentException("Cannot wrap an empty list as NonEmptyList") /** * Returns a [NonEmptyList] that wraps the given [this], avoiding an additional copy. * diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptySet.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptySet.kt index bbe67ccffc..d444a0cb1f 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptySet.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptySet.kt @@ -12,28 +12,34 @@ import kotlin.jvm.JvmExposeBoxed import kotlin.jvm.JvmInline import kotlin.jvm.JvmStatic +@OptIn(PotentiallyUnsafeNonEmptyOperation::class) @JvmInline -public value class NonEmptySet internal constructor( +public value class NonEmptySet @PotentiallyUnsafeNonEmptyOperation internal constructor( @PublishedApi internal val elements: Set ) : Set by elements, NonEmptyCollection { + public constructor(first: E, rest: Iterable) : this(buildNonEmptySet(rest.collectionSizeOrDefault(10) + 1) { + add(first) + addAll(rest) + this + }.elements) + + public override operator fun plus(elements: Iterable<@UnsafeVariance E>): NonEmptySet = buildNonEmptySet(size + elements.collectionSizeOrDefault(10)) { + addAll(this@NonEmptySet) + addAll(elements) + this + } - public constructor(first: E, rest: Iterable) : this(setOf(first) + rest) - - public override operator fun plus(elements: Iterable<@UnsafeVariance E>): NonEmptySet = - NonEmptySet(this.elements + elements) - - public override operator fun plus(element: @UnsafeVariance E): NonEmptySet = - NonEmptySet(this.elements + element) + public override operator fun plus(element: @UnsafeVariance E): NonEmptySet = buildNonEmptySet(size + 1) { + addAll(elements) + add(element) + this + } override fun isEmpty(): Boolean = false @JvmExposeBoxed @Suppress("USELESS_JVM_EXPOSE_BOXED") public fun toSet(): Set = elements - override val head: E get() = elements.first() - - override fun lastOrNull(): E = elements.last() - override fun toString(): String = elements.toString() override fun equals(other: Any?): Boolean = @@ -42,23 +48,24 @@ public value class NonEmptySet internal constructor( override fun hashCode(): Int = elements.hashCode() - public override fun distinct(): NonEmptyList = - NonEmptyList(elements.toList()) + public override fun distinct(): NonEmptyList = toNonEmptyList() - public override fun distinctBy(selector: (E) -> K): NonEmptyList = - NonEmptyList(elements.distinctBy(selector)) + // BEGIN: overrides due to KT-80101 NoSuchMethodError when inheriting function implementations in interfaces + public override fun distinctBy(selector: (E) -> K): NonEmptyList = super.distinctBy(selector) - public override fun map(transform: (E) -> T): NonEmptyList = - NonEmptyList(elements.map(transform)) + public override fun map(transform: (E) -> T): NonEmptyList = super.map(transform) - public override fun flatMap(transform: (E) -> NonEmptyCollection): NonEmptyList = - NonEmptyList(elements.flatMap(transform)) + public override fun flatMap(transform: (E) -> NonEmptyCollection): NonEmptyList = super.flatMap(transform) - public override fun mapIndexed(transform: (index: Int, E) -> T): NonEmptyList = - NonEmptyList(elements.mapIndexed(transform)) + public override fun mapIndexed(transform: (index: Int, E) -> T): NonEmptyList = super.mapIndexed(transform) + // END - override fun zip(other: NonEmptyCollection): NonEmptyList> = - NonEmptyList(elements.zip(other)) + override fun zip(other: NonEmptyCollection): NonEmptyList> = buildNonEmptyList(minOf(size, other.size)) { + val first = this@NonEmptySet.iterator() + val second = other.iterator() + do add(first.next() to second.next()) while (first.hasNext() && second.hasNext()) + this + } public companion object { @JvmStatic @JvmExposeBoxed @@ -91,8 +98,7 @@ public fun nonEmptySetOf(first: E, vararg rest: E): NonEmptySet = * Returns a [NonEmptySet] that contains a **copy** of the elements in [this]. */ @OptIn(PotentiallyUnsafeNonEmptyOperation::class) -public fun Iterable.toNonEmptySetOrNull(): NonEmptySet? = - toSet().wrapAsNonEmptySetOrNull() +public fun Iterable.toNonEmptySetOrNull(): NonEmptySet? = toSet().wrapAsNonEmptySetOrNull() /** * Returns a [NonEmptySet] that contains a **copy** of the elements in [this]. @@ -103,9 +109,7 @@ public fun Iterable.toNonEmptySetOrNone(): Option> = /** * Returns a [NonEmptySet] that contains a **copy** of the elements in [this]. */ -@OptIn(PotentiallyUnsafeNonEmptyOperation::class) -public fun Iterable.toNonEmptySetOrThrow(): NonEmptySet = - toSet().wrapAsNonEmptySetOrThrow() +public fun Iterable.toNonEmptySetOrThrow(): NonEmptySet = toNonEmptySetOrNull() ?: throw IllegalArgumentException("Cannot create NonEmptySet from empty Iterable") @Deprecated("Same as Iterable extension", level = DeprecationLevel.HIDDEN) public fun Set.toNonEmptySetOrNull(): NonEmptySet? = @@ -122,10 +126,7 @@ public fun Set.toNonEmptySetOrNone(): Option> = * You are responsible for keeping the non-emptiness invariant at all times. */ @PotentiallyUnsafeNonEmptyOperation -public fun Set.wrapAsNonEmptySetOrThrow(): NonEmptySet { - require(isNotEmpty()) - return NonEmptySet(this) -} +public fun Set.wrapAsNonEmptySetOrThrow(): NonEmptySet = wrapAsNonEmptySetOrNull() ?: throw IllegalArgumentException("Cannot create NonEmptySet from empty Set") /** * Returns a [NonEmptySet] that wraps the given [this], avoiding an additional copy. diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt index 6a18657988..e76758df87 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt @@ -8,9 +8,16 @@ package arrow.core.raise import arrow.core.Either import arrow.core.EitherNel import arrow.core.Ior +import arrow.core.MonotoneMutableList +import arrow.core.MonotoneMutableSet import arrow.core.NonEmptyList import arrow.core.NonEmptySet import arrow.core.PotentiallyUnsafeNonEmptyOperation +import arrow.core.add +import arrow.core.addAll +import arrow.core.asNonEmptyList +import arrow.core.asNonEmptySet +import arrow.core.buildNonEmptyList import arrow.core.collectionSizeOrDefault import arrow.core.getOrElse import arrow.core.nel @@ -18,7 +25,7 @@ import arrow.core.raise.RaiseAccumulate.Error import arrow.core.raise.RaiseAccumulate.Ok import arrow.core.raise.RaiseAccumulate.Value import arrow.core.toNonEmptyListOrNull -import arrow.core.wrapAsNonEmptySetOrThrow +import arrow.core.wrapAsNonEmptyListOrNull import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind.AT_LEAST_ONCE import kotlin.contracts.InvocationKind.AT_MOST_ONCE @@ -768,7 +775,21 @@ public inline fun Raise>.mapOrAccumulate( // For a NonEmptyList to be returned, there must be a B, which can only be produced by transform // thus transform must be called at least once (or alternatively an error is raised or an exception is thrown etc) contract { callsInPlace(transform, AT_LEAST_ONCE) } - return mapOrAccumulate(nonEmptyList.all) { transform(it) }.let(::NonEmptyList) + val list = MonotoneMutableList(nonEmptyList.size) + return accumulate { + var result: Value>? = null + val iterator = nonEmptyList.iterator() + do result = run { // Once language version is 2.2, we can use continue instead of return@run here + accumulating { + val transformed = transform(iterator.next()) + if (result is RaiseAccumulate.Error) return@run result + list.add(transformed) + if (result != null) return@run result + list.asNonEmptyList() + } + } while (iterator.hasNext()) + result.value + } } /** @@ -778,7 +799,7 @@ public inline fun Raise>.mapOrAccumulate( * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ -@OptIn(PotentiallyUnsafeNonEmptyOperation::class) +@OptIn(ExperimentalRaiseAccumulateApi::class) @RaiseDSL @Suppress("WRONG_INVOCATION_KIND") public inline fun Raise>.mapOrAccumulate( @@ -786,11 +807,20 @@ public inline fun Raise>.mapOrAccumulate( @BuilderInference transform: RaiseAccumulate.(A) -> B ): NonEmptySet { contract { callsInPlace(transform, AT_LEAST_ONCE) } - return buildSet(nonEmptySet.size) { - forEachAccumulatingImpl(nonEmptySet.iterator()) { item, hasErrors -> - transform(item).also { if (!hasErrors) add(it) } - } - }.wrapAsNonEmptySetOrThrow() + val set = MonotoneMutableSet(nonEmptySet.size) + return accumulate { + var result: Value>? = null + val iterator = nonEmptySet.iterator() + do result = run { // Once language version is 2.2, we can use continue instead of return@run here + accumulating { + val transformed = transform(iterator.next()) + if (result is RaiseAccumulate.Error) return@run result + set.add(transformed) + set.asNonEmptySet() + } + } while (iterator.hasNext()) + result.value + } } @RaiseDSL @@ -1096,23 +1126,28 @@ private class RaiseNel(private val accumulate: Accumulate) : Raise @OptIn(ExperimentalRaiseAccumulateApi::class) private class ListAccumulate(private val raise: Raise>) : Accumulate, Raise> { - private val list: MutableList = mutableListOf() - - fun raiseSingle(r: Error): Nothing = raise.raise(NonEmptyList(list + r)) - override fun raise(r: NonEmptyList) = raise.raise(NonEmptyList(list + r.all)) - - // only valid if list is not empty - // errors are never removed from `list`, so once this is valid, it stays valid - private val error = Error { raise.raise(NonEmptyList(list)) } + private val list = MonotoneMutableList() + + fun raiseSingle(r: Error): Nothing = raise.raise(buildNonEmptyList(list.size + 1) { + addAll(list) + add(r) + this + }) + override fun raise(r: NonEmptyList) = raise.raise(buildNonEmptyList(list.size + r.size) { + addAll(list) + addAll(r) + this + }) @ExperimentalRaiseAccumulateApi override fun accumulateAll(errors: NonEmptyList): Value { list.addAll(errors) - return error + return Error { raise.raise(list.asNonEmptyList()) } } + @OptIn(PotentiallyUnsafeNonEmptyOperation::class) @ExperimentalRaiseAccumulateApi - override val latestError: Value? get() = error.takeIf { list.isNotEmpty() } + override val latestError: Value? get() = list.wrapAsNonEmptyListOrNull()?.let { Error { raise.raise(it) } } } @OptIn(ExperimentalRaiseAccumulateApi::class) diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptyListTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptyListTest.kt index 334ca95f82..3d29fa151b 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptyListTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptyListTest.kt @@ -457,16 +457,10 @@ class NonEmptyListTest { @Test fun flatMap() = runTest { - fun transform(i: Int) = listOf(i) + 1 + fun transform(i: Int) = nonEmptyListOf(i, 1) - checkAll(Arb.list(Arb.int(), range = 0..20)) { a -> - val expected = a.flatMap(::transform) - - a.toNonEmptyListOrNull() - ?.flatMap { - transform(it).let(::NonEmptyList) - } - ?.shouldBe(expected) + checkAll(Arb.nonEmptyList(Arb.int(), range = 0..20)) { a -> + a.flatMap(::transform) shouldBe (a as List).flatMap(::transform) } } diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptySetTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptySetTest.kt index 32684808dd..a1366efbc4 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptySetTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptySetTest.kt @@ -237,8 +237,8 @@ class NonEmptySetTest { @Test fun toStringUsesUnderlyingImplementation() = runTest { checkAll(Arb.set(Arb.int(), 1..100)) { - NonEmptySet(it).toString() shouldBe it.toString() - NonEmptySet(MyVerySpecialSet(it)).toString() shouldBe "MyVerySpecialSet(${it.reversed()})" + it.wrapAsNonEmptySetOrThrow().toString() shouldBe it.toString() + MyVerySpecialSet(it).wrapAsNonEmptySetOrThrow().toString() shouldBe "MyVerySpecialSet(${it.reversed()})" } } } diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/test/Generators.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/test/Generators.kt index 3885baf1f0..07e7a8cc71 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/test/Generators.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/test/Generators.kt @@ -7,7 +7,6 @@ import io.kotest.property.arbitrary.bind import io.kotest.property.arbitrary.boolean import io.kotest.property.arbitrary.choice import io.kotest.property.arbitrary.constant -import io.kotest.property.arbitrary.filter import io.kotest.property.arbitrary.int import io.kotest.property.arbitrary.list import io.kotest.property.arbitrary.set @@ -29,13 +28,14 @@ import kotlin.coroutines.startCoroutine // copied from kotest-extensions-arrow +@OptIn(PotentiallyUnsafeNonEmptyOperation::class) fun Arb.Companion.nonEmptyList(arb: Arb, range: IntRange = 0 .. 100): Arb> = Arb.list(arb, max(range.first, 1) .. range.last) - .filter { it.isNotEmpty() } - .map { NonEmptyList(it) } + .map { it.wrapAsNonEmptyListOrThrow() } +@OptIn(PotentiallyUnsafeNonEmptyOperation::class) fun Arb.Companion.nonEmptySet(arb: Arb, range: IntRange = 0 .. 100): Arb> = - Arb.set(arb, max(range.first, 1) .. range.last).map { it.toNonEmptySetOrNull()!! } + Arb.set(arb, max(range.first, 1) .. range.last).map { it.wrapAsNonEmptySetOrThrow() } fun Arb.Companion.sequence(arb: Arb, range: IntRange = 0 .. 100): Arb> = Arb.list(arb, range).map { it.asSequence() }