Skip to content

Instantly share code, notes, and snippets.

@dnene
Created March 13, 2019 18:31
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 dnene/9ad15131de7dc319a2288a53d0079eda to your computer and use it in GitHub Desktop.
Save dnene/9ad15131de7dc319a2288a53d0079eda to your computer and use it in GitHub Desktop.
package tech.dnene.trials2
import arrow.core.*
typealias Error = String
// Strategy A - sealed classes - Requires support for OO/inheritance
sealed class Abstract<A>
data class Value(val i: Int): Abstract<Int>()
data class Fault(val e: String): Abstract<Int>()
class NoValue: Abstract<Int>()
operator fun Abstract<Int>.invoke() = when(this) {
is Value -> { this.toString() }
is Fault -> { this }
is NoValue -> { "Default Message"}
}
// Strategy B - algebraic data types - Requires support for algebraic data types
// .. no classes need to be declared
operator fun Option<Either<Error, Int>>.invoke() =
fold(
{ "Default Message" },
{
it.fold(
{ it },
{ it.toString() })
})
// Strategy C - Church Encoding - Just lambda calculus
interface LoadedData<A> {
operator fun <B> invoke(f: (A)-> B, error: (Error)-> B, data: B): B
}
class Loaded<A>(val a: A): LoadedData<A> {
override operator fun <B> invoke(f: (A) -> B, error: (Error) -> B, data: B): B = f(a)
}
class ErrorT<A>(val e: Error): LoadedData<A> {
override operator fun <B> invoke(f: (A) -> B, error: (Error) -> B, data: B): B = error(e)
}
class LoadingT<A>(): LoadedData<A> {
override operator fun <B> invoke(f: (A) -> B, error: (Error) -> B, data: B): B = data
}
operator fun LoadedData<Int>.invoke() = this({ it.toString() }, { it }, "Default Message")
fun main() {
println("---------- Strategy A ----------")
val a1 = Value(111)
val a2 = Fault("Nan")
val a3 = NoValue()
println(a1())
println(a2())
println(a3())
println("---------- Strategy B ----------")
val b1 = 111.right().some()
val b2 = "Nan".left().some()
val b3 = None
println(b1())
println(b2())
println(b3())
println("---------- Strategy C ----------")
val c1 = Loaded<Int>(111)
val c2 = ErrorT<Int>("NaN")
val c3 = LoadingT<Int>()
println(c1())
println(c2())
println(c3())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment