Disjoint Unions in Kotlin?


#1

Scala uses the "Either" construct -- a disjoint union -- to return sucess or failure from a method call, like this:

def f(i:Int) =

  if(i == 0)

  Left("Divide by zero")

  else

  Right(24/i)

A newer version of Scala clarifies this idea by using "Try" to produce "Success" or "Failure" objects.

Is there anything like this in Kotlin, or is there another approach?

Thanks.


#2

There is no Either class in the standard library yet (it is likely to be added at some point). Meanwhile, you can define your own version of it along the lines of

abstract class Either<out A, out B> private () {   class Left<A>(val value: A): Either<A, Nothing>()   class Right<B>(val value: B): Either<Nothing, B>()

}

Unfortunately, our "when" expressions do not understand that is you check and Either for both Left and Right, it is exhaustive, yet, but this will be supported in the near future.


#3

funKTionale already includes Either for Kotlin

https://github.com/MarioAriasC/funKTionale/wiki/Either


#4

I notice there's no equivalent of Scala's "Try" in funKTionale -- is this a design choice (which I would understand -- I'm not convinced Try is the best solution) or have you simply not gotten around to implementing it?


#5

Still evaluaring, TBH low priority


#6

I know that this topic hasn’t been updated for a while, but this discussion is still very high in search results.

There is now a concept of sealed classes in Kotlin, so Either can be implemented like this:

sealed class Either<out A, out B> {
    class Left<A>(val value: A): Either<A, Nothing>()
    class Right<B>(val value: B): Either<Nothing, B>()
}

In this case, when expression will be exhaustive.


#7

In addition the most popular functional lib for kotlin must be funktionale, which has an either type: https://github.com/MarioAriasC/funKTionale/blob/master/src/main/kotlin/org/funktionale/either/Either.kt


#8

When expressions are exhaustive. When statements are not, I believe. Watch out for that.


#9

Very useful feature.

Having this in standard API with features like default values, composition and transformations would be great.
Is it still considered to be added at some point? In 1.1 would be awesome :slight_smile:

Like ‘?’ operator for nullable types (instead of a monadic Option type) a type Union operator could be a good fit for Kotlin too…

Note : Before I found this post i’ve opened a ticket here https://youtrack.jetbrains.com/issue/KT-12713


#10

Some sample codes from the issue about how the API could look like.

Solution 1, with an Either type :

// return Int representation of s or an error message
fun toInt(s: String): Either<String, Int> = ... 
toInt("1").map{it +1} // Right(2) or Success(2)
toInt("hello").getOrElse(-1) //-1

Solution 2 with a | operator :

// return Int representation of s or an error message
fun toInt(s: String): String|Int = ... 
toInt("1")|.let{it +1} //Right(2) or Success(2)
toInt("hello")|:-1 //-1

Note : i’m not sure about ‘|:’ and ‘|?’ usage, maybe it would be more readable to use regular methods…