-
Notifications
You must be signed in to change notification settings - Fork 449
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Pattern matching with KClass and KProperty * Auto-update API files * Suggestions by @nomisRev --------- Co-authored-by: serras <[email protected]>
- Loading branch information
Showing
19 changed files
with
467 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
public final class arrow/match/BuildersKt { | ||
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 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 fun <init> ()V | ||
public fun fillInStackTrace ()Ljava/lang/Throwable; | ||
} | ||
|
||
public final class arrow/match/MatchKt { | ||
public static final fun matchOrElse (Ljava/lang/Object;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; | ||
public static final fun matchOrRaise (Larrow/core/raise/Raise;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; | ||
public static final fun matchOrRaise (Larrow/core/raise/SingletonRaise;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; | ||
public static final fun matchOrThrow (Ljava/lang/Object;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; | ||
public static synthetic fun matchOrThrow$default (Ljava/lang/Object;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/Object; | ||
public static final fun matchUnit (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V | ||
} | ||
|
||
public final class arrow/match/MatchNotFound : java/lang/Throwable { | ||
public fun <init> (Ljava/lang/Object;)V | ||
public final fun getValue ()Ljava/lang/Object; | ||
} | ||
|
||
public abstract class arrow/match/MatchScope { | ||
public fun <init> ()V | ||
public abstract fun default (Lkotlin/jvm/functions/Function0;)V | ||
public final fun getIt ()Lkotlin/reflect/KProperty1; | ||
public abstract fun then (Lkotlin/reflect/KProperty1;Lkotlin/jvm/functions/Function1;)V | ||
} | ||
|
||
public final class arrow/match/MatcherKt { | ||
public static final fun Matcher (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lkotlin/reflect/KProperty1; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Klib ABI Dump | ||
// Targets: [iosArm64, iosSimulatorArm64, iosX64, js, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, wasmJs, watchosArm32, watchosArm64, watchosSimulatorArm64, watchosX64] | ||
// Rendering settings: | ||
// - Signature version: 2 | ||
// - Show manifest properties: true | ||
// - Show declarations: true | ||
|
||
// Library unique name: <io.arrow-kt:arrow-match> | ||
abstract class <#A: kotlin/Any?, #B: kotlin/Any?> arrow.match/MatchScope { // arrow.match/MatchScope|null[0] | ||
constructor <init>() // arrow.match/MatchScope.<init>|<init>(){}[0] | ||
|
||
final val it // arrow.match/MatchScope.it|{}it[0] | ||
final fun <get-it>(): kotlin.reflect/KProperty1<#A, #A> // arrow.match/MatchScope.it.<get-it>|<get-it>(){}[0] | ||
|
||
abstract fun <#A1: kotlin/Any?> (kotlin.reflect/KProperty1<#A, #A1>).then(kotlin/Function1<#A1, #B>) // arrow.match/MatchScope.then|[email protected]<1:0,0:0>(kotlin.Function1<0:0,1:1>){0§<kotlin.Any?>}[0] | ||
abstract fun default(kotlin/Function0<#B>) // arrow.match/MatchScope.default|default(kotlin.Function0<1:1>){}[0] | ||
final inline fun <#A1: reified #A!!, #B1: kotlin/Any?, #C1: kotlin/Any?, #D1: kotlin/Any?, #E1: kotlin/Any?, #F1: kotlin/Any?> (kotlin.reflect/KClass<#A1>).of(kotlin.reflect/KProperty1<#A1, #B1>, kotlin.reflect/KProperty1<#A1, #C1>, kotlin.reflect/KProperty1<#A1, #D1>, kotlin.reflect/KProperty1<#A1, #E1>, kotlin.reflect/KProperty1<#A1, #F1>): kotlin.reflect/KProperty1<#A, arrow.core/Tuple5<#B1, #C1, #D1, #E1, #F1>> // arrow.match/MatchScope.of|[email protected]<0:0>(kotlin.reflect.KProperty1<0:0,0:1>;kotlin.reflect.KProperty1<0:0,0:2>;kotlin.reflect.KProperty1<0:0,0:3>;kotlin.reflect.KProperty1<0:0,0:4>;kotlin.reflect.KProperty1<0:0,0:5>){0§<1:0>;1§<kotlin.Any?>;2§<kotlin.Any?>;3§<kotlin.Any?>;4§<kotlin.Any?>;5§<kotlin.Any?>}[0] | ||
final inline fun <#A1: reified #A!!, #B1: kotlin/Any?, #C1: kotlin/Any?, #D1: kotlin/Any?, #E1: kotlin/Any?> (kotlin.reflect/KClass<#A1>).of(kotlin.reflect/KProperty1<#A1, #B1>, kotlin.reflect/KProperty1<#A1, #C1>, kotlin.reflect/KProperty1<#A1, #D1>, kotlin.reflect/KProperty1<#A1, #E1>): kotlin.reflect/KProperty1<#A, arrow.core/Tuple4<#B1, #C1, #D1, #E1>> // arrow.match/MatchScope.of|[email protected]<0:0>(kotlin.reflect.KProperty1<0:0,0:1>;kotlin.reflect.KProperty1<0:0,0:2>;kotlin.reflect.KProperty1<0:0,0:3>;kotlin.reflect.KProperty1<0:0,0:4>){0§<1:0>;1§<kotlin.Any?>;2§<kotlin.Any?>;3§<kotlin.Any?>;4§<kotlin.Any?>}[0] | ||
final inline fun <#A1: reified #A!!, #B1: kotlin/Any?, #C1: kotlin/Any?, #D1: kotlin/Any?> (kotlin.reflect/KClass<#A1>).of(kotlin.reflect/KProperty1<#A1, #B1>, kotlin.reflect/KProperty1<#A1, #C1>, kotlin.reflect/KProperty1<#A1, #D1>): kotlin.reflect/KProperty1<#A, kotlin/Triple<#B1, #C1, #D1>> // arrow.match/MatchScope.of|[email protected]<0:0>(kotlin.reflect.KProperty1<0:0,0:1>;kotlin.reflect.KProperty1<0:0,0:2>;kotlin.reflect.KProperty1<0:0,0:3>){0§<1:0>;1§<kotlin.Any?>;2§<kotlin.Any?>;3§<kotlin.Any?>}[0] | ||
final inline fun <#A1: reified #A!!, #B1: kotlin/Any?, #C1: kotlin/Any?> (kotlin.reflect/KClass<#A1>).of(kotlin.reflect/KProperty1<#A1, #B1>, kotlin.reflect/KProperty1<#A1, #C1>): kotlin.reflect/KProperty1<#A, kotlin/Pair<#B1, #C1>> // arrow.match/MatchScope.of|[email protected]<0:0>(kotlin.reflect.KProperty1<0:0,0:1>;kotlin.reflect.KProperty1<0:0,0:2>){0§<1:0>;1§<kotlin.Any?>;2§<kotlin.Any?>}[0] | ||
final inline fun <#A1: reified #A!!, #B1: kotlin/Any?> (kotlin.reflect/KClass<#A1>).of(kotlin.reflect/KProperty1<#A1, #B1>): kotlin.reflect/KProperty1<#A, #B1> // arrow.match/MatchScope.of|[email protected]<0:0>(kotlin.reflect.KProperty1<0:0,0:1>){0§<1:0>;1§<kotlin.Any?>}[0] | ||
} | ||
|
||
final class arrow.match/DoesNotMatch : kotlin/Throwable { // arrow.match/DoesNotMatch|null[0] | ||
constructor <init>() // arrow.match/DoesNotMatch.<init>|<init>(){}[0] | ||
} | ||
|
||
final class arrow.match/MatchNotFound : kotlin/Throwable { // arrow.match/MatchNotFound|null[0] | ||
constructor <init>(kotlin/Any?) // arrow.match/MatchNotFound.<init>|<init>(kotlin.Any?){}[0] | ||
|
||
final val value // arrow.match/MatchNotFound.value|{}value[0] | ||
final fun <get-value>(): kotlin/Any? // arrow.match/MatchNotFound.value.<get-value>|<get-value>(){}[0] | ||
} | ||
|
||
final val arrow.match/isNotEmpty // arrow.match/isNotEmpty|@kotlin.reflect.KProperty1<0:0,kotlin.collections.Collection<0:1>>{0§<kotlin.Any?>;1§<kotlin.Any?>}isNotEmpty[0] | ||
final fun <#A1: kotlin/Any?, #B1: kotlin/Any?> (kotlin.reflect/KProperty1<#A1, kotlin.collections/Collection<#B1>>).<get-isNotEmpty>(): kotlin.reflect/KProperty1<#A1, kotlin.collections/Collection<#B1>> // arrow.match/isNotEmpty.<get-isNotEmpty>|<get-isNotEmpty>@kotlin.reflect.KProperty1<0:0,kotlin.collections.Collection<0:1>>(){0§<kotlin.Any?>;1§<kotlin.Any?>}[0] | ||
|
||
final fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?, #D: kotlin/Any?, #E: kotlin/Any?, #F: kotlin/Any?, #G: kotlin/Any?> (kotlin.reflect/KProperty1<#A, #B>).arrow.match/of(kotlin.reflect/KProperty1<#B, #C>, kotlin.reflect/KProperty1<#B, #D>, kotlin.reflect/KProperty1<#B, #E>, kotlin.reflect/KProperty1<#B, #F>, kotlin.reflect/KProperty1<#B, #G>): kotlin.reflect/KProperty1<#A, arrow.core/Tuple5<#C, #D, #E, #F, #G>> // arrow.match/of|[email protected]<0:0,0:1>(kotlin.reflect.KProperty1<0:1,0:2>;kotlin.reflect.KProperty1<0:1,0:3>;kotlin.reflect.KProperty1<0:1,0:4>;kotlin.reflect.KProperty1<0:1,0:5>;kotlin.reflect.KProperty1<0:1,0:6>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>;3§<kotlin.Any?>;4§<kotlin.Any?>;5§<kotlin.Any?>;6§<kotlin.Any?>}[0] | ||
final fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?, #D: kotlin/Any?, #E: kotlin/Any?, #F: kotlin/Any?> (kotlin.reflect/KProperty1<#A, #B>).arrow.match/of(kotlin.reflect/KProperty1<#B, #C>, kotlin.reflect/KProperty1<#B, #D>, kotlin.reflect/KProperty1<#B, #E>, kotlin.reflect/KProperty1<#B, #F>): kotlin.reflect/KProperty1<#A, arrow.core/Tuple4<#C, #D, #E, #F>> // arrow.match/of|[email protected]<0:0,0:1>(kotlin.reflect.KProperty1<0:1,0:2>;kotlin.reflect.KProperty1<0:1,0:3>;kotlin.reflect.KProperty1<0:1,0:4>;kotlin.reflect.KProperty1<0:1,0:5>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>;3§<kotlin.Any?>;4§<kotlin.Any?>;5§<kotlin.Any?>}[0] | ||
final fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?, #D: kotlin/Any?, #E: kotlin/Any?> (kotlin.reflect/KProperty1<#A, #B>).arrow.match/of(kotlin.reflect/KProperty1<#B, #C>, kotlin.reflect/KProperty1<#B, #D>, kotlin.reflect/KProperty1<#B, #E>): kotlin.reflect/KProperty1<#A, kotlin/Triple<#C, #D, #E>> // arrow.match/of|[email protected]<0:0,0:1>(kotlin.reflect.KProperty1<0:1,0:2>;kotlin.reflect.KProperty1<0:1,0:3>;kotlin.reflect.KProperty1<0:1,0:4>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>;3§<kotlin.Any?>;4§<kotlin.Any?>}[0] | ||
final fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?, #D: kotlin/Any?> (kotlin.reflect/KProperty1<#A, #B>).arrow.match/of(kotlin.reflect/KProperty1<#B, #C>, kotlin.reflect/KProperty1<#B, #D>): kotlin.reflect/KProperty1<#A, kotlin/Pair<#C, #D>> // arrow.match/of|[email protected]<0:0,0:1>(kotlin.reflect.KProperty1<0:1,0:2>;kotlin.reflect.KProperty1<0:1,0:3>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>;3§<kotlin.Any?>}[0] | ||
final fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?> (arrow.core.raise/SingletonRaise<#C>).arrow.match/matchOrRaise(#A, kotlin/Function1<arrow.match/MatchScope<#A, #B>, kotlin/Unit>): #B // arrow.match/matchOrRaise|[email protected]<0:2>(0:0;kotlin.Function1<arrow.match.MatchScope<0:0,0:1>,kotlin.Unit>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>}[0] | ||
final fun <#A: kotlin/Any?, #B: kotlin/Any?, #C: kotlin/Any?> (kotlin.reflect/KProperty1<#A, #B>).arrow.match/of(kotlin.reflect/KProperty1<#B, #C>): kotlin.reflect/KProperty1<#A, #C> // arrow.match/of|[email protected]<0:0,0:1>(kotlin.reflect.KProperty1<0:1,0:2>){0§<kotlin.Any?>;1§<kotlin.Any?>;2§<kotlin.Any?>}[0] | ||
final fun <#A: kotlin/Any?, #B: kotlin/Any?> (#A).arrow.match/matchOrElse(kotlin/Function0<#B>, kotlin/Function1<arrow.match/MatchScope<#A, #B>, kotlin/Unit>): #B // arrow.match/matchOrElse|matchOrElse@0:0(kotlin.Function0<0:1>;kotlin.Function1<arrow.match.MatchScope<0:0,0:1>,kotlin.Unit>){0§<kotlin.Any?>;1§<kotlin.Any?>}[0] | ||
final fun <#A: kotlin/Any?, #B: kotlin/Any?> (#A).arrow.match/matchOrThrow(kotlin/Function0<kotlin/Throwable> = ..., kotlin/Function1<arrow.match/MatchScope<#A, #B>, kotlin/Unit>): #B // arrow.match/matchOrThrow|matchOrThrow@0:0(kotlin.Function0<kotlin.Throwable>;kotlin.Function1<arrow.match.MatchScope<0:0,0:1>,kotlin.Unit>){0§<kotlin.Any?>;1§<kotlin.Any?>}[0] | ||
final fun <#A: kotlin/Any?, #B: kotlin/Any?> (arrow.core.raise/Raise<arrow.match/MatchNotFound>).arrow.match/matchOrRaise(#A, kotlin/Function1<arrow.match/MatchScope<#A, #B>, kotlin/Unit>): #B // arrow.match/matchOrRaise|[email protected]<arrow.match.MatchNotFound>(0:0;kotlin.Function1<arrow.match.MatchScope<0:0,0:1>,kotlin.Unit>){0§<kotlin.Any?>;1§<kotlin.Any?>}[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|[email protected]<0:0,0:1>(kotlin.String?;kotlin.Function1<0:1,kotlin.Boolean>){0§<kotlin.Any?>;1§<kotlin.Any?>}[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§<kotlin.Any?>;1§<kotlin.Any?>}[0] | ||
final fun <#A: kotlin/Any?> (#A).arrow.match/matchUnit(kotlin/Function1<arrow.match/MatchScope<#A, kotlin/Unit>, kotlin/Unit>) // arrow.match/matchUnit|matchUnit@0:0(kotlin.Function1<arrow.match.MatchScope<0:0,kotlin.Unit>,kotlin.Unit>){0§<kotlin.Any?>}[0] | ||
final fun <#A: kotlin/Any?> arrow.match/identity(): kotlin.reflect/KProperty1<#A, #A> // arrow.match/identity|identity(){0§<kotlin.Any?>}[0] | ||
final inline fun <#A: kotlin/Any?, #B: reified #A> arrow.match/instanceOf(): kotlin.reflect/KProperty1<#A, #B> // arrow.match/instanceOf|instanceOf(){0§<kotlin.Any?>;1§<0:0>}[0] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
@file:Suppress("DSL_SCOPE_VIOLATION") | ||
|
||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile | ||
|
||
|
||
plugins { | ||
id(libs.plugins.kotlin.multiplatform.get().pluginId) | ||
alias(libs.plugins.arrowGradleConfig.kotlin) | ||
alias(libs.plugins.publish) | ||
alias(libs.plugins.spotless) | ||
} | ||
|
||
spotless { | ||
kotlin { | ||
ktlint().editorConfigOverride(mapOf("ktlint_standard_filename" to "disabled")) | ||
} | ||
} | ||
|
||
apply(from = property("ANIMALSNIFFER_MPP")) | ||
|
||
kotlin { | ||
sourceSets { | ||
commonMain { | ||
dependencies { | ||
implementation(libs.kotlin.stdlib) | ||
implementation(projects.arrowCore) | ||
} | ||
} | ||
commonTest { | ||
dependencies { | ||
implementation(libs.kotlin.test) | ||
implementation(libs.kotest.assertionsCore) | ||
implementation(libs.coroutines.test) | ||
} | ||
} | ||
} | ||
|
||
jvm { | ||
tasks.jvmJar { | ||
manifest { | ||
attributes["Automatic-Module-Name"] = "arrow.match" | ||
} | ||
} | ||
} | ||
} | ||
|
||
// enables context receivers for Jvm Tests | ||
tasks.named<KotlinCompile>("compileTestKotlinJvm") { | ||
compilerOptions.freeCompilerArgs.add("-Xcontext-receivers") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Maven publishing configuration | ||
POM_NAME=Arrow Match |
88 changes: 88 additions & 0 deletions
88
arrow-libs/optics/arrow-match/src/commonMain/kotlin/arrow/match/Builders.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package arrow.match | ||
|
||
import arrow.core.Tuple4 | ||
import arrow.core.Tuple5 | ||
import kotlin.reflect.KProperty1 | ||
|
||
/** | ||
* A matcher is a [KProperty1] which may throw [DoesNotMatch] | ||
* to signal that it does not match the value. | ||
*/ | ||
public typealias Matcher<S, A> = KProperty1<S, A> | ||
|
||
public expect fun <S, A> Matcher( | ||
name: String, | ||
get: (S) -> A | ||
): Matcher<S, A> | ||
|
||
public expect class DoesNotMatch(): Throwable | ||
|
||
public fun <S> identity(): Matcher<S, S> = Matcher("identity") { it } | ||
|
||
public inline fun <S, reified A: S> instanceOf(): Matcher<S, A> = | ||
Matcher("instanceOf<${A::class.simpleName}>") { | ||
if (it is A) it else throw DoesNotMatch() | ||
} | ||
|
||
public fun <S, A> Matcher<S, A>.takeIf( | ||
description: String? = null, | ||
predicate: (A) -> Boolean | ||
): Matcher<S, A> = Matcher("${this.name}.${description ?: "suchThat"}") { | ||
val value = this.get(it) | ||
if (predicate(value)) value else throw DoesNotMatch() | ||
} | ||
|
||
public val <S, A> Matcher<S, Collection<A>>.isNotEmpty: Matcher<S, Collection<A>> | ||
get() = this.takeIf("isNotEmpty") { it.isNotEmpty() } | ||
|
||
public fun <S, A, B> Matcher<S, A>.of( | ||
field: Matcher<A, B> | ||
): Matcher<S, B> = Matcher("${this.name}.of(${field.name})") { | ||
field.get(this.get(it)) | ||
} | ||
|
||
public fun <S, A, B, C> Matcher<S, A>.of( | ||
field1: Matcher<A, B>, | ||
field2: Matcher<A, C> | ||
): Matcher<S, Pair<B, C>> = Matcher( | ||
"${this.name}.of(${field1.name}, ${field2.name})" | ||
) { | ||
val a = this.get(it) | ||
Pair(field1.get(a), field2.get(a)) | ||
} | ||
|
||
public fun <S, A, B, C, D> Matcher<S, A>.of( | ||
field1: Matcher<A, B>, | ||
field2: Matcher<A, C>, | ||
field3: Matcher<A, D> | ||
): Matcher<S, Triple<B, C, D>> = Matcher( | ||
"${this.name}.of(${field1.name}, ${field2.name}, ${field3.name})" | ||
) { | ||
val a = this.get(it) | ||
Triple(field1.get(a), field2.get(a), field3.get(a)) | ||
} | ||
|
||
public fun <S, A, B, C, D, E> Matcher<S, A>.of( | ||
field1: Matcher<A, B>, | ||
field2: Matcher<A, C>, | ||
field3: Matcher<A, D>, | ||
field4: Matcher<A, E> | ||
): Matcher<S, Tuple4<B, C, D, E>> = Matcher( | ||
"${this.name}.of(${field1.name}, ${field2.name}, ${field3.name}, ${field4.name})" | ||
) { | ||
val a = this.get(it) | ||
Tuple4(field1.get(a), field2.get(a), field3.get(a), field4.get(a)) | ||
} | ||
|
||
public fun <S, A, B, C, D, E, F> Matcher<S, A>.of( | ||
field1: Matcher<A, B>, | ||
field2: Matcher<A, C>, | ||
field3: Matcher<A, D>, | ||
field4: Matcher<A, E>, | ||
field5: Matcher<A, F> | ||
): Matcher<S, Tuple5<B, C, D, E, F>> = Matcher( | ||
"${this.name}.of(${field1.name}, ${field2.name}, ${field3.name}, ${field4.name}, ${field5.name})" | ||
) { | ||
val a = this.get(it) | ||
Tuple5(field1.get(a), field2.get(a), field3.get(a), field4.get(a), field5.get(a)) | ||
} |
91 changes: 91 additions & 0 deletions
91
arrow-libs/optics/arrow-match/src/commonMain/kotlin/arrow/match/Match.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package arrow.match | ||
|
||
import arrow.core.Tuple4 | ||
import arrow.core.Tuple5 | ||
import kotlin.reflect.KClass | ||
import arrow.core.raise.Raise | ||
import arrow.core.raise.SingletonRaise | ||
|
||
public abstract class MatchScope<S, R> { | ||
public abstract infix fun <A> Matcher<S, A>.then(next: (A) -> R) | ||
public abstract fun default(next: () -> R) | ||
|
||
public val it: Matcher<S, S> = Matcher("it") { it } | ||
|
||
public inline fun <reified A: S & Any, B> KClass<A>.of( | ||
field: Matcher<A, B> | ||
): Matcher<S, B> = instanceOf<S, A>().of(field) | ||
|
||
public inline fun <reified A: S & Any, B, C> KClass<A>.of( | ||
field1: Matcher<A, B>, | ||
field2: Matcher<A, C> | ||
): Matcher<S, Pair<B, C>> = instanceOf<S, A>().of(field1, field2) | ||
|
||
public inline fun <reified A: S & Any, B, C, D> KClass<A>.of( | ||
field1: Matcher<A, B>, | ||
field2: Matcher<A, C>, | ||
field3: Matcher<A, D> | ||
): Matcher<S, Triple<B, C, D>> = instanceOf<S, A>().of(field1, field2, field3) | ||
|
||
public inline fun <reified A: S & Any, B, C, D, E> KClass<A>.of( | ||
field1: Matcher<A, B>, | ||
field2: Matcher<A, C>, | ||
field3: Matcher<A, D>, | ||
field4: Matcher<A, E> | ||
): Matcher<S, Tuple4<B, C, D, E>> = instanceOf<S, A>().of(field1, field2, field3, field4) | ||
|
||
public inline fun <reified A: S & Any, B, C, D, E, F> KClass<A>.of( | ||
field1: Matcher<A, B>, | ||
field2: Matcher<A, C>, | ||
field3: Matcher<A, D>, | ||
field4: Matcher<A, E>, | ||
field5: Matcher<A, F> | ||
): Matcher<S, Tuple5<B, C, D, E, F>> = instanceOf<S, A>().of(field1, field2, field3, field4, field5) | ||
} | ||
|
||
private class MatchScopeImpl<S, R>(val subject: S): MatchScope<S, R>() { | ||
override fun <A> Matcher<S, A>.then(next: (A) -> R) { | ||
try { | ||
this.get(subject)?.let { throw MatchFound(next(it)) } | ||
} catch (e: DoesNotMatch) { | ||
/* do nothing */ | ||
} | ||
} | ||
override fun default(next: () -> R) { | ||
throw MatchFound(next()) | ||
} | ||
} | ||
|
||
private class MatchFound(val result: Any?) : Throwable() | ||
|
||
@Suppress("UNCHECKED_CAST") | ||
public fun <S, R> S.matchOrElse( | ||
noMatch: () -> R, | ||
cases: MatchScope<S, R>.() -> Unit, | ||
): R = try { | ||
cases(MatchScopeImpl(this)) | ||
noMatch() | ||
} catch (e: MatchFound) { | ||
e.result as R | ||
} | ||
|
||
public class MatchNotFound(public val value: Any?) : Throwable() | ||
|
||
public fun <S, R> S.matchOrThrow( | ||
exception: () -> Throwable = { MatchNotFound(this) }, | ||
cases: MatchScope<S, R>.() -> Unit, | ||
): R = matchOrElse({ throw exception() }, cases) | ||
|
||
public fun <S, R> Raise<MatchNotFound>.matchOrRaise( | ||
value: S, | ||
cases: MatchScope<S, R>.() -> Unit, | ||
): R = value.matchOrElse({ raise(MatchNotFound(value)) }, cases) | ||
|
||
public fun <S, R, E> SingletonRaise<E>.matchOrRaise( | ||
value: S, | ||
cases: MatchScope<S, R>.() -> Unit, | ||
): R = value.matchOrElse({ raise() }, cases) | ||
|
||
public fun <S> S.matchUnit( | ||
cases: MatchScope<S, Unit>.() -> Unit, | ||
): Unit = matchOrElse({ }, cases) |
11 changes: 11 additions & 0 deletions
11
arrow-libs/optics/arrow-match/src/jsMain/kotlin/arrow/match/Matcher.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package arrow.match | ||
|
||
@Suppress("IMPLEMENTING_FUNCTION_INTERFACE") | ||
public actual fun <S, A> Matcher( | ||
name: String, | ||
get: (S) -> A | ||
): Matcher<S, A> = object : Matcher<S, A> { | ||
override val name: String = name | ||
override fun get(receiver: S): A = get(receiver) | ||
override fun invoke(receiver: S): A = get(receiver) | ||
} |
Oops, something went wrong.