Skip to content

Instantly share code, notes, and snippets.

@happy-bracket
Created January 16, 2020 09:05
Show Gist options
  • Save happy-bracket/baa3e601cb9e258b6186d168b3441278 to your computer and use it in GitHub Desktop.
Save happy-bracket/baa3e601cb9e258b6186d168b3441278 to your computer and use it in GitHub Desktop.
Free monad, but in Kotlin!
fun main() {
val result = Free.fx<ForStore, String> {
put("arrow", "huita").bind()
update<String>("arrow") { "let's me do this" }.bind()
val arrow = get<String>("arrow").bind()
put("arrow-huita", "I have spoken").bind()
delete("arrow-huita")
arrow ?: ""
}
println(result)
}
fun <F, A> Free.Companion.fx(comp: suspend MonadSyntax<FreePartialOf<F>>.() -> A): Free<F, A> =
Free.monad<F>().fx.monad(comp).fix()
class ForStore private constructor()
sealed class StoreA<A> : Kind<ForStore, A>
data class Put<A>(val key: String, val value: A) : StoreA<Unit>()
data class Get<A>(val key: String) : StoreA<A?>()
data class Delete(val key: String) : StoreA<Unit>()
typealias Store<A> = Free<ForStore, A>
fun <T> put(key: String, value: T): Store<Unit> = Free.liftF(Put(key, value))
fun <T> get(key: String): Store<T?> = Free.liftF(Get(key))
fun delete(key: String): Store<Unit> = Free.liftF(Delete(key))
fun <T> update(key: String, upd: (T) -> T): Store<Unit> {
return Free.fx<ForStore, Unit> {
val value = get<T>(key).bind()
val res = value?.let(upd)?.let { put(key, it) } ?: Free.just(Unit)
res.bind()
}.fix()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment