Created
October 17, 2015 19:45
-
-
Save speedcom/baeab41c65b48d0b68e9 to your computer and use it in GitHub Desktop.
Scala Monad For-Comprehension
This file contains 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
/** A for comprehension ready Monad */ | |
case class Focomo[A](value: A) { | |
self => | |
/** satisfies monadic binding of a function f that returns B */ | |
def map[B](f: A => B): Focomo[B] = { | |
println("map!"); | |
Focomo(f(value)) | |
} | |
/** satisfies monadic binding of a function f that returns Focomo[B] */ | |
def flatMap[B](f: A => Focomo[B]): Focomo[B] = { | |
println("flatMap!"); | |
f(value) | |
} | |
/** expect this to be called in a `Unit` for comprehension */ | |
def foreach[U](f: A => U): Unit = { | |
println("foreach!"); | |
f(value) | |
} | |
/** for comprehension's `if` statements trigger this. | |
* In a more useful monad, the result of the application | |
* of a value to function f would determine the a special subclass | |
* of the monad or other either-or behavior. | |
*/ | |
def filter(f: A => Boolean): Focomo[A] = { | |
println("filter!"); | |
this | |
} | |
/** provides a delegate handler for calls to #withFilter */ | |
class WithFilter(p: A => Boolean) { | |
println("with filter!") | |
def map[B](f: A => B): Focomo[B] = self.filter(p).map(f) | |
def flatMap[B](f: A => Focomo[B]): Focomo[B] = self.filter(p).flatMap(f) | |
def foreach[U](f: A => U): Unit = self.filter(p).foreach(f) | |
def withFilter(q: A => Boolean): WithFilter = | |
new WithFilter(x => p(x) && q(x)) | |
} | |
/** called with conditional statement in for comprehension */ | |
def withFilter(p: A => Boolean): WithFilter = new WithFilter(p) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment