Skip to content

Instantly share code, notes, and snippets.

@jamesward
Created August 4, 2021 16:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesward/2ae81fd44272e3619a87e9dda7fd16f2 to your computer and use it in GitHub Desktop.
Save jamesward/2ae81fd44272e3619a87e9dda7fd16f2 to your computer and use it in GitHub Desktop.
sealed class Result<out V, out E> {
data class Failure<out FE>(val e: FE): Result<Nothing, FE>()
data class Success<out SV>(val v: SV): Result<SV, Nothing>()
companion object {
fun <PV> succeed(v: PV): Result<PV, Nothing> = Success(v)
fun <PE> fail(e: PE): Result<Nothing, PE> = Failure(e)
}
inline fun <MR> map(f: (V) -> MR): Result<MR, E> {
return flatMap { v ->
Success(f(v))
}
}
@Suppress("UNCHECKED_CAST")
inline fun <FR, FE> flatMap(f: (V) -> Result<FR, FE>): Result<FR, FE> {
return when(this) {
is Failure -> this as Result<FR, FE>
is Success -> f(v)
}
}
}
fun main() {
fun toLength(s: String): Result<Int, Nothing> {
return Result.Success(s.length)
}
// Monad Laws
// Left Identity Law
require(
Result.succeed("asdf").flatMap(::toLength) == toLength("asdf") &&
Result.succeed("asdf").flatMap { Result.fail("err") } == Result.fail("err")
)
// Right Identity Law
require(
Result.succeed("asdf").flatMap { Result.succeed(it) } == Result.succeed("asdf") &&
Result.fail("err").flatMap { Result.succeed(it) } == Result.fail("err")
)
// Associativity Law
fun reverse(s: String): Result<String, Nothing> = Result.succeed(s.reversed())
require(
Result.succeed("asdf").flatMap(::reverse).flatMap(::toLength) == Result.succeed("asdf").flatMap { reverse(it).flatMap(::toLength) }
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment