Created
October 9, 2016 02:26
-
-
Save raymondtay/aa466eb6a12e146a554feeea320e5d6b 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 scalaz._ | |
| import Scalaz._ | |
| case class Result(eCode: Int) | |
| case class Action(z: Int, f : Int => Int) | |
| // Artificially created two "steps" with the intention | |
| // combining them later in a composition | |
| val step1 = State[Action, Result] { | |
| case (a: Action) => | |
| (Action(a.f(a.z), a.f), Result(0)) | |
| } | |
| val step2 = State[Action, Result] { | |
| case (a: Action) => | |
| (Action(a.f(a.z), a.f), Result(1)) | |
| } | |
| // I wanted to have step3 consume the result | |
| // of step1 . step2 | |
| val step3 = State[Result, Result] { | |
| case (r: Result) if r.eCode == 1 => (r, r) | |
| case _ => (new Result(-1), new Result(-1)) | |
| } | |
| def doTwoSteps : State[Action, Result] = | |
| for { | |
| _a <- step1 | |
| _b <- step2 | |
| } yield new Result(_a.eCode + _b.eCode) | |
| // this expression is the same as `doTwoSteps`; just wanted to see how the sugar syntax unrolls | |
| def doTwoSteps2 : State[Action, Result] = step1 >>= { (r: Result) => for { _r <- step2 } yield new Result(_r.eCode + r.eCode) } // ignoring the result of the first action | |
| println("doTwoSteps : " + doTwoSteps(Action(1, (x: Int) => x + 1))) | |
| println("doTwoSteps2 : " + doTwoSteps2(Action(1, (x: Int) => x + 1))) | |
| // | |
| // I explore monadic composition via Kleisli category | |
| // two ways to construct a Kleisli "function" | |
| // (a) via the companion object, "Kleisli" | |
| // (b) via the 'kleisli' function of the companion object. | |
| // | |
| def f :scalaz.Kleisli[Id,Action,(Action, Result)] = Kleisli { (input: Action) => doTwoSteps(input) } | |
| def g = Kleisli.kleisli{ (i1: Action) => step1(i1) } | |
| def h = Kleisli.kleisli{ (i2: (Action,Result)) => step2(i2._1) } | |
| def ff = h <=< g | |
| println("calling kleisli function 'f': " + f(Action(1, (x: Int) => x + 1))) | |
| println("calling composed kleisli function 'ff' : " + ff(Action(1, (x: Int) => x + 1))) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment