From 3615561b86ad269c3cbf3ec667ed2b152bfab04d Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Mena Date: Wed, 2 Oct 2024 18:44:52 +0200 Subject: [PATCH] Suggestions by @nomisRev --- .../optics/arrow-match/api/arrow-match.api | 11 ++++++----- .../arrow-match/api/arrow-match.klib.api | 14 ++++++++------ .../commonMain/kotlin/arrow/match/Builders.kt | 18 +++++++++--------- .../src/commonMain/kotlin/arrow/match/Match.kt | 10 +++++----- .../jvmMain/kotlin/arrow/match/DoesNotMatch.kt | 6 ++++++ .../src/jvmTest/kotlin/arrow/match/Simple.kt | 4 ++-- .../kotlin/arrow/match/DoesNotMatch.kt | 3 +++ .../optics/arrow-optics/api/arrow-optics.api | 2 +- .../arrow-optics/api/arrow-optics.klib.api | 2 +- .../kotlin/arrow/optics/match/Combinators.kt | 4 ++-- .../kotlin/arrow/optics/match/MatchTest.kt | 4 ++-- 11 files changed, 45 insertions(+), 33 deletions(-) create mode 100644 arrow-libs/optics/arrow-match/src/jvmMain/kotlin/arrow/match/DoesNotMatch.kt create mode 100644 arrow-libs/optics/arrow-match/src/nonJvmMain/kotlin/arrow/match/DoesNotMatch.kt diff --git a/arrow-libs/optics/arrow-match/api/arrow-match.api b/arrow-libs/optics/arrow-match/api/arrow-match.api index ba64c2f8c10..1cf7bdcc800 100644 --- a/arrow-libs/optics/arrow-match/api/arrow-match.api +++ b/arrow-libs/optics/arrow-match/api/arrow-match.api @@ -1,17 +1,18 @@ public final class arrow/match/BuildersKt { - public static final fun getNotEmpty (Lkotlin/reflect/KProperty1;)Lkotlin/reflect/KProperty1; + public static final fun identity ()Lkotlin/reflect/KProperty1; + public static final fun isNotEmpty (Lkotlin/reflect/KProperty1;)Lkotlin/reflect/KProperty1; public static final fun of (Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;)Lkotlin/reflect/KProperty1; public static final fun of (Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;)Lkotlin/reflect/KProperty1; public static final fun of (Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;)Lkotlin/reflect/KProperty1; public static final fun of (Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;)Lkotlin/reflect/KProperty1; public static final fun of (Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;Lkotlin/reflect/KProperty1;)Lkotlin/reflect/KProperty1; - public static final fun self ()Lkotlin/reflect/KProperty1; - public static final fun suchThat (Lkotlin/reflect/KProperty1;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lkotlin/reflect/KProperty1; - public static synthetic fun suchThat$default (Lkotlin/reflect/KProperty1;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/reflect/KProperty1; + public static final fun takeIf (Lkotlin/reflect/KProperty1;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lkotlin/reflect/KProperty1; + public static synthetic fun takeIf$default (Lkotlin/reflect/KProperty1;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/reflect/KProperty1; } public final class arrow/match/DoesNotMatch : java/lang/Throwable { - public static final field INSTANCE Larrow/match/DoesNotMatch; + public fun ()V + public fun fillInStackTrace ()Ljava/lang/Throwable; } public final class arrow/match/MatchKt { diff --git a/arrow-libs/optics/arrow-match/api/arrow-match.klib.api b/arrow-libs/optics/arrow-match/api/arrow-match.klib.api index 0db53466017..d22420bf0f5 100644 --- a/arrow-libs/optics/arrow-match/api/arrow-match.klib.api +++ b/arrow-libs/optics/arrow-match/api/arrow-match.klib.api @@ -18,6 +18,9 @@ abstract class <#A: kotlin/Any?, #B: kotlin/Any?> arrow.match/MatchScope { // ar final val it // arrow.match/MatchScope.it|{}it[0] final fun (): kotlin.reflect/KProperty1<#A, #A> // arrow.match/MatchScope.it.|(){}[0] } +final class arrow.match/DoesNotMatch : kotlin/Throwable { // arrow.match/DoesNotMatch|null[0] + constructor () // arrow.match/DoesNotMatch.|(){}[0] +} final class arrow.match/MatchNotFound : kotlin/Throwable { // arrow.match/MatchNotFound|null[0] constructor (kotlin/Any?) // arrow.match/MatchNotFound.|(kotlin.Any?){}[0] final val value // arrow.match/MatchNotFound.value|{}value[0] @@ -32,11 +35,10 @@ final fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?> (kotlin.reflect/KP final fun <#A: kotlin/Any?, #B: kotlin/Any?> (#A).arrow.match/matchOrElse(kotlin/Function0<#B>, kotlin/Function1, kotlin/Unit>): #B // arrow.match/matchOrElse|matchOrElse@0:0(kotlin.Function0<0:1>;kotlin.Function1,kotlin.Unit>){0§;1§}[0] final fun <#A: kotlin/Any?, #B: kotlin/Any?> (#A).arrow.match/matchOrThrow(kotlin/Function0 = ..., kotlin/Function1, kotlin/Unit>): #B // arrow.match/matchOrThrow|matchOrThrow@0:0(kotlin.Function0;kotlin.Function1,kotlin.Unit>){0§;1§}[0] final fun <#A: kotlin/Any?, #B: kotlin/Any?> (arrow.core.raise/Raise).arrow.match/matchOrRaise(#A, kotlin/Function1, kotlin/Unit>): #B // arrow.match/matchOrRaise|matchOrRaise@arrow.core.raise.Raise(0:0;kotlin.Function1,kotlin.Unit>){0§;1§}[0] -final fun <#A: kotlin/Any?, #B: kotlin/Any?> (kotlin.reflect/KProperty1<#A, #B>).arrow.match/suchThat(kotlin/String? = ..., kotlin/Function1<#B, kotlin/Boolean>): kotlin.reflect/KProperty1<#A, #B> // arrow.match/suchThat|suchThat@kotlin.reflect.KProperty1<0:0,0:1>(kotlin.String?;kotlin.Function1<0:1,kotlin.Boolean>){0§;1§}[0] +final fun <#A: kotlin/Any?, #B: kotlin/Any?> (kotlin.reflect/KProperty1<#A, #B>).arrow.match/takeIf(kotlin/String? = ..., kotlin/Function1<#B, kotlin/Boolean>): kotlin.reflect/KProperty1<#A, #B> // arrow.match/takeIf|takeIf@kotlin.reflect.KProperty1<0:0,0:1>(kotlin.String?;kotlin.Function1<0:1,kotlin.Boolean>){0§;1§}[0] final fun <#A: kotlin/Any?, #B: kotlin/Any?> arrow.match/Matcher(kotlin/String, kotlin/Function1<#A, #B>): kotlin.reflect/KProperty1<#A, #B> // arrow.match/Matcher|Matcher(kotlin.String;kotlin.Function1<0:0,0:1>){0§;1§}[0] final fun <#A: kotlin/Any?> (#A).arrow.match/matchUnit(kotlin/Function1, kotlin/Unit>) // arrow.match/matchUnit|matchUnit@0:0(kotlin.Function1,kotlin.Unit>){0§}[0] -final fun <#A: kotlin/Any?> arrow.match/self(): kotlin.reflect/KProperty1<#A, #A> // arrow.match/self|self(){0§}[0] -final inline fun <#A: kotlin/Any?, #B: reified #A> arrow.match/it(): kotlin.reflect/KProperty1<#A, #B> // arrow.match/it|it(){0§;1§<0:0>}[0] -final object arrow.match/DoesNotMatch : kotlin/Throwable // arrow.match/DoesNotMatch|null[0] -final val arrow.match/notEmpty // arrow.match/notEmpty|@kotlin.reflect.KProperty1<0:0,kotlin.collections.Collection<0:1>>{0§;1§}notEmpty[0] - final fun <#A1: kotlin/Any?, #B1: kotlin/Any?> (kotlin.reflect/KProperty1<#A1, kotlin.collections/Collection<#B1>>).(): kotlin.reflect/KProperty1<#A1, kotlin.collections/Collection<#B1>> // arrow.match/notEmpty.|@kotlin.reflect.KProperty1<0:0,kotlin.collections.Collection<0:1>>(){0§;1§}[0] +final fun <#A: kotlin/Any?> arrow.match/identity(): kotlin.reflect/KProperty1<#A, #A> // arrow.match/identity|identity(){0§}[0] +final inline fun <#A: kotlin/Any?, #B: reified #A> arrow.match/instanceOf(): kotlin.reflect/KProperty1<#A, #B> // arrow.match/instanceOf|instanceOf(){0§;1§<0:0>}[0] +final val arrow.match/isNotEmpty // arrow.match/isNotEmpty|@kotlin.reflect.KProperty1<0:0,kotlin.collections.Collection<0:1>>{0§;1§}isNotEmpty[0] + final fun <#A1: kotlin/Any?, #B1: kotlin/Any?> (kotlin.reflect/KProperty1<#A1, kotlin.collections/Collection<#B1>>).(): kotlin.reflect/KProperty1<#A1, kotlin.collections/Collection<#B1>> // arrow.match/isNotEmpty.|@kotlin.reflect.KProperty1<0:0,kotlin.collections.Collection<0:1>>(){0§;1§}[0] diff --git a/arrow-libs/optics/arrow-match/src/commonMain/kotlin/arrow/match/Builders.kt b/arrow-libs/optics/arrow-match/src/commonMain/kotlin/arrow/match/Builders.kt index 9e45469a057..65cdb1bdbf8 100644 --- a/arrow-libs/optics/arrow-match/src/commonMain/kotlin/arrow/match/Builders.kt +++ b/arrow-libs/optics/arrow-match/src/commonMain/kotlin/arrow/match/Builders.kt @@ -15,25 +15,25 @@ public expect fun Matcher( get: (S) -> A ): Matcher -public object DoesNotMatch: Throwable() +public expect class DoesNotMatch(): Throwable -public fun self(): Matcher = Matcher("self") { it } +public fun identity(): Matcher = Matcher("identity") { it } -public inline fun it(): Matcher = - Matcher("is<${A::class.simpleName}>") { - if (it is A) it else throw DoesNotMatch +public inline fun instanceOf(): Matcher = + Matcher("instanceOf<${A::class.simpleName}>") { + if (it is A) it else throw DoesNotMatch() } -public fun Matcher.suchThat( +public fun Matcher.takeIf( description: String? = null, predicate: (A) -> Boolean ): Matcher = Matcher("${this.name}.${description ?: "suchThat"}") { val value = this.get(it) - if (predicate(value)) value else throw DoesNotMatch + if (predicate(value)) value else throw DoesNotMatch() } -public val Matcher>.notEmpty: Matcher> - get() = this.suchThat("notEmpty") { it.isNotEmpty() } +public val Matcher>.isNotEmpty: Matcher> + get() = this.takeIf("isNotEmpty") { it.isNotEmpty() } public fun Matcher.of( field: Matcher diff --git a/arrow-libs/optics/arrow-match/src/commonMain/kotlin/arrow/match/Match.kt b/arrow-libs/optics/arrow-match/src/commonMain/kotlin/arrow/match/Match.kt index 452a3e01c44..48206bc44ce 100644 --- a/arrow-libs/optics/arrow-match/src/commonMain/kotlin/arrow/match/Match.kt +++ b/arrow-libs/optics/arrow-match/src/commonMain/kotlin/arrow/match/Match.kt @@ -14,25 +14,25 @@ public abstract class MatchScope { public inline fun KClass.of( field: Matcher - ): Matcher = it().of(field) + ): Matcher = instanceOf().of(field) public inline fun KClass.of( field1: Matcher, field2: Matcher - ): Matcher> = it().of(field1, field2) + ): Matcher> = instanceOf().of(field1, field2) public inline fun KClass.of( field1: Matcher, field2: Matcher, field3: Matcher - ): Matcher> = it().of(field1, field2, field3) + ): Matcher> = instanceOf().of(field1, field2, field3) public inline fun KClass.of( field1: Matcher, field2: Matcher, field3: Matcher, field4: Matcher - ): Matcher> = it().of(field1, field2, field3, field4) + ): Matcher> = instanceOf().of(field1, field2, field3, field4) public inline fun KClass.of( field1: Matcher, @@ -40,7 +40,7 @@ public abstract class MatchScope { field3: Matcher, field4: Matcher, field5: Matcher - ): Matcher> = it().of(field1, field2, field3, field4, field5) + ): Matcher> = instanceOf().of(field1, field2, field3, field4, field5) } private class MatchScopeImpl(val subject: S): MatchScope() { diff --git a/arrow-libs/optics/arrow-match/src/jvmMain/kotlin/arrow/match/DoesNotMatch.kt b/arrow-libs/optics/arrow-match/src/jvmMain/kotlin/arrow/match/DoesNotMatch.kt new file mode 100644 index 00000000000..594a206e437 --- /dev/null +++ b/arrow-libs/optics/arrow-match/src/jvmMain/kotlin/arrow/match/DoesNotMatch.kt @@ -0,0 +1,6 @@ +package arrow.match + +public actual class DoesNotMatch: Throwable() { + // disable stacktrace creation + override fun fillInStackTrace(): Throwable = this +} diff --git a/arrow-libs/optics/arrow-match/src/jvmTest/kotlin/arrow/match/Simple.kt b/arrow-libs/optics/arrow-match/src/jvmTest/kotlin/arrow/match/Simple.kt index f7a6132e9bd..bbbbb23e9ec 100644 --- a/arrow-libs/optics/arrow-match/src/jvmTest/kotlin/arrow/match/Simple.kt +++ b/arrow-libs/optics/arrow-match/src/jvmTest/kotlin/arrow/match/Simple.kt @@ -17,13 +17,13 @@ data class Company( ): User val User.shownName: String get() = this.matchOrThrow { - Person::class.of(Person::name.of(Name::firstName), Person::age.suchThat { it < 18 }) then { (fn, _) -> fn } + Person::class.of(Person::name.of(Name::firstName), Person::age.takeIf { it < 18 }) then { (fn, _) -> fn } Person::class.of(Person::name.of(Name::firstName, Name::lastName)) then { (fn, ln) -> "Sir/Madam $fn $ln" } Company::class.of(Company::name, Company::director.of(Name::lastName)) then { (nm, d) -> "$nm, att. $d" } } val Person.shownNameForPerson: String get() = this.matchOrThrow { - it.of(Person::name.of(Name::firstName), Person::age.suchThat { it < 18 }) then { (fn, _) -> fn } + it.of(Person::name.of(Name::firstName), Person::age.takeIf { it < 18 }) then { (fn, _) -> fn } it.of(Person::name.of(Name::firstName, Name::lastName)) then { (fn, ln) -> "Sir/Madam $fn $ln" } } diff --git a/arrow-libs/optics/arrow-match/src/nonJvmMain/kotlin/arrow/match/DoesNotMatch.kt b/arrow-libs/optics/arrow-match/src/nonJvmMain/kotlin/arrow/match/DoesNotMatch.kt new file mode 100644 index 00000000000..bf031c60c18 --- /dev/null +++ b/arrow-libs/optics/arrow-match/src/nonJvmMain/kotlin/arrow/match/DoesNotMatch.kt @@ -0,0 +1,3 @@ +package arrow.match + +public actual class DoesNotMatch: Throwable() diff --git a/arrow-libs/optics/arrow-optics/api/arrow-optics.api b/arrow-libs/optics/arrow-optics/api/arrow-optics.api index cec5833f7f4..f32022eabfe 100644 --- a/arrow-libs/optics/arrow-optics/api/arrow-optics.api +++ b/arrow-libs/optics/arrow-optics/api/arrow-optics.api @@ -535,7 +535,7 @@ public final class arrow/optics/match/CombinatorsKt { public static final fun it (Larrow/optics/POptional;Larrow/optics/POptional;Larrow/optics/POptional;Larrow/optics/POptional;)Larrow/optics/POptional; public static final fun it (Larrow/optics/POptional;Larrow/optics/POptional;Larrow/optics/POptional;Larrow/optics/POptional;Larrow/optics/POptional;)Larrow/optics/POptional; public static final fun predicate (Lkotlin/jvm/functions/Function1;)Larrow/optics/POptional; - public static final fun suchThat (Larrow/optics/POptional;Lkotlin/jvm/functions/Function1;)Larrow/optics/POptional; + public static final fun takeIf (Larrow/optics/POptional;Lkotlin/jvm/functions/Function1;)Larrow/optics/POptional; } public final class arrow/optics/match/MatchKt { diff --git a/arrow-libs/optics/arrow-optics/api/arrow-optics.klib.api b/arrow-libs/optics/arrow-optics/api/arrow-optics.klib.api index e7278c9dbda..c72014c2004 100644 --- a/arrow-libs/optics/arrow-optics/api/arrow-optics.klib.api +++ b/arrow-libs/optics/arrow-optics/api/arrow-optics.klib.api @@ -282,7 +282,7 @@ final fun <#A: kotlin/Any?, #B: kotlin/Any?> (arrow.core.raise/Raise (arrow.optics/PLens<#A, #A, kotlin.collections/Set<#B>, kotlin.collections/Set<#B>>).arrow.optics.dsl/at(#B): arrow.optics/PLens<#A, #A, kotlin/Boolean, kotlin/Boolean> // arrow.optics.dsl/at|at@arrow.optics.PLens<0:0,0:0,kotlin.collections.Set<0:1>,kotlin.collections.Set<0:1>>(0:1){0§;1§}[0] final fun <#A: kotlin/Any?, #B: kotlin/Any?> (arrow.optics/PLens<#B, #B, kotlin.collections/List<#A>, kotlin.collections/List<#A>>).arrow.optics/get(kotlin/Int): arrow.optics/POptional<#B, #B, #A, #A> // arrow.optics/get|get@arrow.optics.PLens<0:1,0:1,kotlin.collections.List<0:0>,kotlin.collections.List<0:0>>(kotlin.Int){0§;1§}[0] final fun <#A: kotlin/Any?, #B: kotlin/Any?> (arrow.optics/POptional<#A, #A, #B, #B>).arrow.optics.match/ifEquals(#B): arrow.optics/POptional<#A, #A, #B, #B> // arrow.optics.match/ifEquals|ifEquals@arrow.optics.POptional<0:0,0:0,0:1,0:1>(0:1){0§;1§}[0] -final fun <#A: kotlin/Any?, #B: kotlin/Any?> (arrow.optics/POptional<#A, #A, #B, #B>).arrow.optics.match/suchThat(kotlin/Function1<#B, kotlin/Boolean>): arrow.optics/POptional<#A, #A, #B, #B> // arrow.optics.match/suchThat|suchThat@arrow.optics.POptional<0:0,0:0,0:1,0:1>(kotlin.Function1<0:1,kotlin.Boolean>){0§;1§}[0] +final fun <#A: kotlin/Any?, #B: kotlin/Any?> (arrow.optics/POptional<#A, #A, #B, #B>).arrow.optics.match/takeIf(kotlin/Function1<#B, kotlin/Boolean>): arrow.optics/POptional<#A, #A, #B, #B> // arrow.optics.match/takeIf|takeIf@arrow.optics.POptional<0:0,0:0,0:1,0:1>(kotlin.Function1<0:1,kotlin.Boolean>){0§;1§}[0] final fun <#A: kotlin/Any?, #B: kotlin/Any?> (arrow.optics/POptional<#A, #A, arrow.core/NonEmptyList<#B>, arrow.core/NonEmptyList<#B>>).arrow.optics.dsl/index(kotlin/Int): arrow.optics/POptional<#A, #A, #B, #B> // arrow.optics.dsl/index|index@arrow.optics.POptional<0:0,0:0,arrow.core.NonEmptyList<0:1>,arrow.core.NonEmptyList<0:1>>(kotlin.Int){0§;1§}[0] final fun <#A: kotlin/Any?, #B: kotlin/Any?> (arrow.optics/POptional<#A, #A, kotlin.collections/List<#B>, kotlin.collections/List<#B>>).arrow.optics.dsl/index(kotlin/Int): arrow.optics/POptional<#A, #A, #B, #B> // arrow.optics.dsl/index|index@arrow.optics.POptional<0:0,0:0,kotlin.collections.List<0:1>,kotlin.collections.List<0:1>>(kotlin.Int){0§;1§}[0] final fun <#A: kotlin/Any?, #B: kotlin/Any?> (arrow.optics/POptional<#A, #A, kotlin.collections/Set<#B>, kotlin.collections/Set<#B>>).arrow.optics.dsl/at(#B): arrow.optics/POptional<#A, #A, kotlin/Boolean, kotlin/Boolean> // arrow.optics.dsl/at|at@arrow.optics.POptional<0:0,0:0,kotlin.collections.Set<0:1>,kotlin.collections.Set<0:1>>(0:1){0§;1§}[0] diff --git a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/match/Combinators.kt b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/match/Combinators.kt index 01f969bd318..aeb1701d7ca 100644 --- a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/match/Combinators.kt +++ b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/match/Combinators.kt @@ -8,7 +8,7 @@ import arrow.core.raise.ensure import arrow.optics.Optional import arrow.optics.Prism -public fun Optional.suchThat( +public fun Optional.takeIf( predicate: (A) -> Boolean, ): Optional = this.compose(predicate(predicate)) @@ -24,7 +24,7 @@ public fun predicate( set = { x, _ -> x } ) -public fun Optional.ifEquals(value: A): Optional = this.suchThat { it == value } +public fun Optional.ifEquals(value: A): Optional = this.takeIf { it == value } public fun equalsTo(value: A): Optional = predicate { it == value } diff --git a/arrow-libs/optics/arrow-optics/src/commonTest/kotlin/arrow/optics/match/MatchTest.kt b/arrow-libs/optics/arrow-optics/src/commonTest/kotlin/arrow/optics/match/MatchTest.kt index 0f7dfc1cb76..cfcde0575f8 100644 --- a/arrow-libs/optics/arrow-optics/src/commonTest/kotlin/arrow/optics/match/MatchTest.kt +++ b/arrow-libs/optics/arrow-optics/src/commonTest/kotlin/arrow/optics/match/MatchTest.kt @@ -62,13 +62,13 @@ data class Company( } val User.shownName: String get() = this.matchOrThrow { - User.person(Person.name(Name.firstName), Person.age.suchThat { it < 18 }) then { (fn, _) -> fn } + User.person(Person.name(Name.firstName), Person.age.takeIf { it < 18 }) then { (fn, _) -> fn } User.person(Person.name(Name.firstName, Name.lastName)) then { (fn, ln) -> "Sir/Madam $fn $ln" } User.company(Company.name, Company.director(Name.lastName)) then { (nm, d) -> "$nm, att. $d" } } val Person.shownNameForPerson: String get() = this.matchOrThrow { - it(Person.name(Name.firstName), Person.age.suchThat { it < 18 }) then { (fn, _) -> fn } + it(Person.name(Name.firstName), Person.age.takeIf { it < 18 }) then { (fn, _) -> fn } it(Person.name(Name.firstName, Name.lastName)) then { (fn, ln) -> "Sir/Madam $fn $ln" } }