Skip to content

Instantly share code, notes, and snippets.

@exallium
Created September 21, 2016 18:47
Show Gist options
  • Select an option

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

Select an option

Save exallium/a9db4c55736002d662fa65fccf2339b9 to your computer and use it in GitHub Desktop.
monads
package main;
sealed class Maybe<A>(private val a: A?) {
class Just<A>(a: A) : Maybe<A>(a) {
override fun toString() = "Just(${wrapped()})"
}
class None<A> : Maybe<A>(null) {
override fun toString() = "None"
}
protected fun wrapped(): A? = a
fun <B> of(b: B): Maybe<out B> = Just(b)
fun <B> fromNullable(b: B?): Maybe<out B> = if (b == null) { None<B>() } else { of(b) }
fun <B> map(mapFn: (A?) -> (B)): Maybe<out B> = fromNullable(mapFn(wrapped()))
fun <B> flatMap(flatMapFn: (A?) -> (Maybe<out B>)): Maybe<out B> = flatMapFn(wrapped())
}
sealed class Either<A>(private val a: A) {
class Left<A>(a: A) : Either<A>(a) {
override fun <B> of(b: B): Either<out B> = Left<B>(b)
override fun toString() = "Left(${wrapped()})"
}
class Right<A>(a: A) : Either<A>(a) {
override fun <B> of(b: B): Either<out B> = Right<B>(b)
override fun toString() = "Right(${wrapped()})"
}
protected fun wrapped(): A = a
abstract fun <B> of(b: B): Either<out B>
fun <B> map(mapFn: (A) -> (B)): Either<out B> = of(mapFn(wrapped()))
fun <B> flatMap(flatMapFn: (A) -> (Either<out B>)): Either<out B> = flatMapFn(wrapped())
}
fun <T> processMaybe(m: Maybe<T>): String {
return when(m) {
is Maybe.Just<T> -> "found just $m"
is Maybe.None<T> -> "found none $m"
}
}
fun <T> processEither(e: Either<T>): String {
return when(e) {
is Either.Right<T> -> "found right $e"
is Either.Left<T> -> "found left $e"
}
}
fun main(args: Array<String>) {
val a = Maybe.Just(4)
val b = a.map { null }
println(processMaybe(a))
println(processMaybe(b))
val response = Either.Left(4)
val next = response.flatMap {
if (it > 3) {
Either.Right(Exception("Something bad happened"))
} else {
Either.Left(it + 1)
}
}
println(processEither(response))
println(processEither(next))
}
@exallium

Copy link
Copy Markdown
Author

Output

found just Just(4)
found none None
found left Left(4)
found right Right(java.lang.Exception: Something bad happened)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment