Created
September 16, 2018 17:07
-
-
Save Mishkun/9430a6740858876895c1eb0f870b7a59 to your computer and use it in GitHub Desktop.
This is an example of how the pattern-matching could work in Kotlin, if all data classes implemented a `ComponentN` interface implicitly, additionaly to just generate the `componentN()` methods.
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
package com.mishkun.components | |
interface Component2<T1, T2> { | |
fun component1(): T1 | |
fun component2(): T2 | |
} | |
interface Matcher<T> { | |
fun matches(value: T): Boolean | |
} | |
class AnyMatcher<T>: Matcher<T> { | |
override fun matches(value: T): Boolean = true | |
} | |
fun <T> any() = AnyMatcher<T>() | |
class ExactMatcher<T>(val expected: T): Matcher<T> { | |
override fun matches(value: T): Boolean = expected == value | |
} | |
class Pattern<T1, T2>(val matcher1: Matcher<T1>, val matcher2: Matcher<T2>) { | |
operator fun <T : Component2<T1, T2>> contains(value: T): Boolean = | |
matcher1.matches(value.component1()) && matcher2.matches(value.component2()) | |
} | |
fun <T1, T2> ((T1, T2) -> Component2<T1, T2>).pattern(exact: T1, matcher: Matcher<T2>) = | |
Pattern(ExactMatcher(exact), matcher) | |
fun <T1, T2> ((T1, T2) -> Component2<T1, T2>).pattern(matcher: Matcher<T1>, exact: T2) = | |
Pattern(matcher, ExactMatcher(exact)) | |
data class User(val name: String, val age: Int) : Component2<String, Int> | |
fun main(args: Array<String>) { | |
val users = listOf( | |
User(name = "John Doe", age = 27), | |
User(name = "Peter The Great", age = 21), | |
User(name = "Xiao Ming", age = 13) | |
) | |
for ((pos, user) in users.mapIndexed(::Pair)) | |
when (user) { | |
in ::User.pattern("John Doe", any()) -> | |
println("Found John Doe!, his position is $pos") | |
in ::User.pattern(any(), 13) -> | |
println("Found someone aged 13, his position is $pos") | |
else -> println("This is not the user we are looking for at $pos ;(") | |
} | |
} | |
/* | |
This outputs: | |
Found John Doe!, his position is 0 | |
This is not the user we are looking for at 1 ;( | |
Found someone aged 13, his position is 2 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment