Skip to content

Instantly share code, notes, and snippets.

@nomisRev
Created October 29, 2017 22:45
Show Gist options
  • Select an option

  • Save nomisRev/89004d77d548dd9910725bf63077a556 to your computer and use it in GitHub Desktop.

Select an option

Save nomisRev/89004d77d548dd9910725bf63077a556 to your computer and use it in GitHub Desktop.
import kategory.*
typealias Stack = ListKW<Int>
/* Normal function */
fun pop(stack: Stack): Either<String, Tuple2<Stack, Int>> =
if (stack.isNotEmpty()) (stack.drop(1).k() toT stack.first()).right()
else "Stack is empty".left()
/* Normal function */
fun push(a: Int, stack: Stack): Stack = (listOf(a) + stack).k()
/* wrapped as state */
fun pushState(a: Int) = StateT<EitherKindPartial<String>, Stack, Unit>(run = { stack: Stack ->
(push(a, stack) toT Unit).right()
})
/* alternative wrapped as state */
fun pushState2(a: Int) = StateT.modify<EitherKindPartial<String>, Stack> { push(a, it).right() }
fun stackManip() = StateT.monad<EitherKindPartial<String>, Stack>().binding {
pushState(3).bind()
::pop.stateT().bind()
val i = ::pop.stateT().bind()
yields(i)
}.ev()
fun stackyStack() = State.monad<Stack>().binding {
val stackNow = State.get<Stack>().bind()
val r = (if (stackNow == listOf(1, 2, 3).k()) State.put(listOf(8, 3, 1).k())
else State.put(listOf(9, 2, 1).k())).bind()
yields(r)
}.ev()
fun main(args: Array<String>) {
stackManip().runM(listOf(5, 8, 2, 1).k()).let(::println)
stackManip().runM(listOf<Int>().k()).let(::println)
stackyStack().run(listOf(1, 2, 3).k()).let(::println)
}
/**
* Pop written in monad binding style
*/
fun pop2() = State.monad<Stack>().binding {
val s = State.get<Stack>().bind()
val (head, tail) = s.first() toT s.drop(1).k()
State.put(tail).bind()
yields(head)
}
/**
* Push written in monad binding style
*/
fun push2(x: Int) = State.monad<Stack>().binding {
val xs = State.get<Stack>().bind()
State.put((listOf(x).k() + xs).k()).bind()
yields(Unit)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment