Skip to content

Instantly share code, notes, and snippets.

@lispyclouds
Last active May 7, 2019 18:46
Show Gist options
  • Save lispyclouds/28a770dfa3ca920219fba2e87549a0eb to your computer and use it in GitHub Desktop.
Save lispyclouds/28a770dfa3ca920219fba2e87549a0eb to your computer and use it in GitHub Desktop.
Monads: Simple made Easy.
import java.util.Scanner
sealed class Maybe<out T>
data class Just<T>(val value: T) : Maybe<T>()
object None : Maybe<Nothing>() {
override fun toString() = "None"
}
fun <T, R> bind(m: Maybe<T>, f: (T) -> Maybe<R>) = when (m) {
is Just<T> -> f(m.value)
else -> None
}
fun <T> unit(v: T) = Just(v)
fun <T> chain(init: Maybe<T>, vararg effects: (T) -> Maybe<T>) = effects.fold(init, ::bind)
fun readAndAdd(prevNum: Int) = try {
print("Enter a number: ")
val num = Scanner(System.`in`).nextLine().toInt()
Just(prevNum + num)
} catch (e: Exception) {
None
}
fun main() {
val result = chain(
unit(0),
::readAndAdd,
::readAndAdd,
::readAndAdd
)
println(result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment