-
-
Save caiorss/43ce7fb62bafa5995cc836b5a2744fbb to your computer and use it in GitHub Desktop.
Reader Monad
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
/// REPL Testing | |
// | |
// ----------------------------------------- | |
$ scala | |
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_20). | |
Type in expressions for evaluation. Or try :help. | |
scala> case class Reader[C, A](g: C => A) { | |
| def apply(c: C) = g(c) | |
| | |
| def map[B](f: A => B): Reader[C, B] = { | |
| Reader{ c => f(g(c)) } | |
| } | |
| | |
| def flatMap[B](f: A => Reader[C, B]): Reader[C, B] = { | |
| Reader{ c => f(g(c))(c) } | |
| } | |
| } | |
defined class Reader | |
scala> val r = Reader ((x: Int) => x + 10) | |
r: Reader[Int,Int] = Reader(<function1>) | |
scala> r.apply(10) | |
res0: Int = 20 | |
scala> r.map(x => x * 3) | |
res1: Reader[Int,Int] = Reader(<function1>) | |
scala> r.map(x => x * 3).map( x => x + 5) | |
res2: Reader[Int,Int] = Reader(<function1>) | |
/// Map is Equivalent to function composition | |
scala> r.map(x => x * 3).apply(10) | |
res3: Int = 60 | |
scala> r.map(x => x * 3).map(x => x + 5).apply(4) | |
res4: Int = 47 | |
//-- flatMap is equivalent to Haskell bind | |
// | |
scala> r.flatMap(x => Reader(a => 10 * a + x)).apply(3) | |
res6: Int = 43 | |
scala> r.flatMap(x => Reader(a => 10 * a + x)).apply(5) | |
res7: Int = 65 | |
scala> r.flatMap(x => Reader(a => 10 * a + x)).apply(6) | |
res8: Int = 76 | |
/// Create a monadic function | |
scala> val fn = (x: Int) => Reader((a: Int) => 10 * a + x) | |
fn: Int => Reader[Int,Int] = <function1> | |
scala> r.flatMap(fn) | |
res9: Reader[Int,Int] = Reader(<function1>) | |
scala> r.flatMap(fn).apply(3) | |
res10: Int = 43 | |
scala> val fm = (x: Int) => Reader((a: Int) => 5 * a - 3 * x) | |
fm: Int => Reader[Int,Int] = <function1> | |
scala> r.flatMap(fn).flatMap(fm) | |
res11: Reader[Int,Int] = Reader(<function1>) | |
scala> r.flatMap(fn).flatMap(fm).apply(3) | |
res12: Int = -114 | |
scala> r.flatMap(fn).flatMap(fm).apply(6) | |
res13: Int = -198 | |
scala> r flatMap fn flatMap fm apply 6 | |
res15: Int = -198 | |
for { | |
a <- r | |
x <- fn(5) | |
y <- fm(6) | |
} yield (a + x + y) | |
scala> for { | |
| a <- r | |
| x <- fn(5) | |
| y <- fm(6) | |
| } yield (a + x + y) | |
res16: Reader[Int,Int] = Reader(<function1>) | |
val m = for { | |
a <- r | |
x <- fn(5) | |
y <- fm(6) | |
} yield (a + x + y) | |
scala> m | |
res17: Reader[Int,Int] = Reader(<function1>) | |
// a = r.apply(4) = 14 | |
// x = fn(5).apply(4) = 45 | |
// y = fm(6).apply(4) = 2 | |
// a + x + y = 61 Ok. | |
// | |
scala> m.apply(4) | |
res18: Int = 61 | |
scala> m.apply(5) | |
res19: Int = 77 |
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
case class Reader[C, A](g: C => A) { | |
def apply(c: C) = g(c) | |
def map[B](f: A => B): Reader[C, B] = { | |
Reader{ c => f(g(c)) } | |
} | |
def flatMap[B](f: A => Reader[C, B]): Reader[C, B] = { | |
Reader{ c => f(g(c))(c) } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment