Skip to content

Instantly share code, notes, and snippets.

@exallium
Last active February 2, 2017 17:13
Show Gist options
  • Select an option

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

Select an option

Save exallium/93750464ddef462f2256eabdf65f66e2 to your computer and use it in GitHub Desktop.
package com.exallium.librarytestbed
sealed class Interactor<out T> {
class Tell<out T>(val msg: String, val t: T) : Interactor<T>() {
override fun <B> flatMap(f: (T) -> B): Interactor<B> {
return Tell(msg, f(t))
}
}
class Ask<out T>(val k: (String) -> T) : Interactor<T>() {
override fun <B> flatMap(f: (T) -> B): Interactor<B> {
return Ask({ f(k(it)) })
}
}
class ExitSuccess<out T> : Interactor<T>() {
override fun <B> flatMap(f: (T) -> B): Interactor<B> {
return ExitSuccess()
}
}
abstract fun <B> flatMap(f: (T) -> B): Interactor<B>
}
class Free<out A : Interactor<T>, out T>(val a: A) {
fun <B: Interactor<U>, U> flatMap(f: (A) -> Free<B, U>): Free<B, U> {
return f(a)
}
}
fun <T> putStrLn(msg: String, next: T) = Free(Interactor.Tell(msg, next))
fun <T> getLine(k: (String) -> T) = Free(Interactor.Ask(k))
fun exitSuccess() = Free(Interactor.ExitSuccess<Unit>())
fun <A : Interactor<T>, T> runOnConsole(free: Free<A, T>) {
when (free.a) {
is Interactor.Ask<*> -> {
val input = "test input"
runOnConsole(free.flatMap { free.a.k(input) as Free<Interactor<Any>, Any> })
}
is Interactor.Tell<*> -> {
println(free.a.msg)
runOnConsole(free.flatMap { free.a.t as Free<Interactor<Any>, Any> })
}
is Interactor.ExitSuccess<*> -> {
//exitProcess(0)
}
}
}
val echo = putStrLn("hello", getLine({ putStrLn(it, exitSuccess()) }))
fun main(args: Array<String>) {
runOnConsole(echo)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment