Skip to content

Instantly share code, notes, and snippets.

@exallium
Last active November 21, 2016 14:42
Show Gist options
  • Select an option

  • Save exallium/d214b250c1666cdb0be9923b94a5976c to your computer and use it in GitHub Desktop.

Select an option

Save exallium/d214b250c1666cdb0be9923b94a5976c to your computer and use it in GitHub Desktop.
sealed class Either<L, R> {
class Left<L, R>(val l: L) : Either<L, R>() {
override fun toString(): String = "Left $l"
}
class Right<L, R>(val r: R) : Either<L, R>() {
override fun toString(): String = "Right $r"
}
infix fun <Rp> bind(f: (R) -> (Either<L, Rp>)): Either<L, Rp> {
return when (this) {
is Either.Left<L, R> -> Left<L, Rp>(this.l)
is Either.Right<L, R> -> f(this.r)
}
}
infix fun <Rp> seq(e: Either<L, Rp>): Either<L, Rp> = e
companion object {
fun <L, R> ret(a: R) = Either.Right<L, R>(a)
fun <L, R> fail(msg: String): Either.Right<L, R> = throw Exception(msg)
}
}
fun main(args: Array<String>) {
println(Either.Right<String, Int>(5) bind { it -> Either.ret<String, Boolean>(true)} )
println(Either.Left<String, Int>("error").bind({ it -> Either.ret<String, Int>(it + 1) }))
val right = Either.Right<String, Int>(5)
val condition = { it: Int -> if (it > 3) {
Either.Left<String, Int>("number is too big")
} else {
Either.Right<String, Int>(it * 2)
}}
println(right bind condition)
println(Either.Right<String, Int>(2).bind(condition).bind(condition).seq(Either.Right<String, Float>(2.0f)))
try {
println(Either.Right<String, Int>(5) bind { Either.fail<String, Int>("asdf") })
} catch (e: Exception) {
println("exception: ${e.message}")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment