Created
October 29, 2017 22:45
-
-
Save nomisRev/89004d77d548dd9910725bf63077a556 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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