From be6a353bec9bd6a113038311b35ff6d9fc570624 Mon Sep 17 00:00:00 2001
From: DBotThePony <dbotthepony@yandex.ru>
Date: Sat, 8 Mar 2025 17:29:28 +0700
Subject: [PATCH] Implement left and right as subclasses in Either

---
 gradle.properties                             |  2 +-
 .../ru/dbotthepony/kommons/util/Either.kt     | 31 +++++++++++++++----
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index b815800..b530ef8 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -4,7 +4,7 @@ kotlin.code.style=official
 specifyKotlinAsDependency=false
 
 projectGroup=ru.dbotthepony.kommons
-projectVersion=3.3.0
+projectVersion=3.3.1
 
 guavaDepVersion=33.0.0
 gsonDepVersion=2.8.9
diff --git a/src/main/kotlin/ru/dbotthepony/kommons/util/Either.kt b/src/main/kotlin/ru/dbotthepony/kommons/util/Either.kt
index 5753d3d..0b618d9 100644
--- a/src/main/kotlin/ru/dbotthepony/kommons/util/Either.kt
+++ b/src/main/kotlin/ru/dbotthepony/kommons/util/Either.kt
@@ -3,7 +3,28 @@ package ru.dbotthepony.kommons.util
 /**
  * Implements a value container which contain either [L] or [R] value
  */
-class Either<L, R> private constructor(val left: KOptional<L>, val right: KOptional<R>) {
+sealed class Either<L, R> {
+	private class Left<L, R>(override val left: KOptional<L>) : Either<L, R>() {
+		override val right: KOptional<R>
+			get() = KOptional()
+
+		override fun swap(): Either<R, L> {
+			return Right(left)
+		}
+	}
+
+	private class Right<L, R>(override val right: KOptional<R>) : Either<L, R>() {
+		override val left: KOptional<L>
+			get() = KOptional()
+
+		override fun swap(): Either<R, L> {
+			return Left(right)
+		}
+	}
+
+	abstract val left: KOptional<L>
+	abstract val right: KOptional<R>
+
 	val isLeft: Boolean get() = left.isPresent
 	val isRight: Boolean get() = right.isPresent
 
@@ -63,19 +84,17 @@ class Either<L, R> private constructor(val left: KOptional<L>, val right: KOptio
 		}
 	}
 
-	fun swap(): Either<R, L> {
-		return Either(right, left)
-	}
+	abstract fun swap(): Either<R, L>
 
 	companion object {
 		@JvmStatic
 		fun <L, R> left(value: L): Either<L, R> {
-			return Either(KOptional.of(value), KOptional.empty())
+			return Left(KOptional(value))
 		}
 
 		@JvmStatic
 		fun <L, R> right(value: R): Either<L, R> {
-			return Either(KOptional.empty(), KOptional.of(value))
+			return Right(KOptional(value))
 		}
 	}
 }