Skip to content

Instantly share code, notes, and snippets.

@raulraja
Created October 4, 2017 15:09
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 raulraja/40ac0d0f03f4a1a85f6d249464f30a95 to your computer and use it in GitHub Desktop.
Save raulraja/40ac0d0f03f4a1a85f6d249464f30a95 to your computer and use it in GitHub Desktop.
import kategory.*
sealed class NukeException {
object SystemOffline: NukeException()
object RotationNeedsOil: NukeException()
data class MissedByMeters(val meters:Int): NukeException()
}
object Nuke
object Target
object Impacted
typealias SystemOffline = NukeException.SystemOffline
typealias RotationNeedsOil = NukeException.RotationNeedsOil
typealias MissedByMeters = NukeException.MissedByMeters
inline fun <reified F> arm(ME:MonadError<F, NukeException> = monadError()):
HK<F, Nuke> = ME.pure(Nuke)
inline fun <reified F> aim(ME:MonadError<F, NukeException> = monadError()):
HK<F, Target> = ME.pure(Target)
inline fun <reified F> launch(target: Target, nuke: Nuke, ME:MonadError<F, NukeException> = monadError()):
HK<F, Impacted> = ME.raiseError(MissedByMeters(5))
inline fun <reified F> attack(ME:MonadError<F, NukeException> = monadError()):HK<F, Impacted> =
ME.binding {
val nuke = arm<F>().bind()
val target = aim<F>().bind()
val impact = launch<F>(target, nuke).bind()
yields(impact)
}
inline fun <reified F> attack1(ME:MonadError<F, NukeException> = monadError()):HK<F, Impacted> =
ME.tupled(aim(), arm()).flatMap(ME, { (nuke, target) -> launch<F>(nuke, target) })
fun main(args:Array<String>) {
attack<EitherKindPartial<NukeException>>() // this will automatically retriev the monad error instance from either
attack(Either.monadError())
attack1<EitherKindPartial<NukeException>>()
}
@nomisRev
Copy link

nomisRev commented Oct 4, 2017

On line 34 you can just use flatMap { (nuke, target) -> launch<F>(nuke, target) } syntax

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment