Skip to content

Instantly share code, notes, and snippets.

@speedcom
Created October 17, 2015 19:45
Show Gist options
  • Save speedcom/baeab41c65b48d0b68e9 to your computer and use it in GitHub Desktop.
Save speedcom/baeab41c65b48d0b68e9 to your computer and use it in GitHub Desktop.

Revisions

  1. speedcom created this gist Oct 17, 2015.
    39 changes: 39 additions & 0 deletions monad.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,39 @@
    /** 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)
    }