I'm looking at the following code for handling errors in Scala:
package challenge1
import core._, Syntax._
sealed trait Error
case class Explosion(exception: Throwable) extends Error
case object NotFound extends Error
case object InvalidRequest extends Error
case object InvalidMethod extends Error
case object Unauthorized extends Error
object Error {
implicit def ErrorEqual =
Equal.derived[Error]
}
case class Fail[A](error: Error) extends Result[A]
case class Ok[A](value: A) extends Result[A]
sealed trait Result[A] {
def fold[X](
fail: Error => X,
ok: A => X
): X = this match {
case Fail(error) => fail(error)
case Ok(value) => ok(value)
}
def map[B](f: A => B): Result[B] =
flatMap(f andThen Result.ok)
def flatMap[B](f: A => Result[B]): Result[B] =
fold(Result.fail, f)
def getOrElse(otherwise: => A): A =
fold(_ => otherwise, identity)
def |||(alternative: => Result[A]): Result[A] =
fold(_ => alternative, _ => this)
}
...
Now I can see code here for handling exceptions using the Maybe Monad in Clojure:
(use '[clojure.contrib.monads :only [maybe-m]])
(defmacro maybe
([bindings return]
`(domonad maybe-m ~bindings ~return))
([bindings return else]
`(let [result# (maybe ~bindings ~return)]
(if (nil? result#)
~else
result#))))
Here Jim Duey explains exception handling in terms of continuations:
(defn mf-a [x]
(println "starting mf-a")
(fn [c]
(println "completing mf-a")
(c (inc x))))
(defn mf-b [x]
(println "starting mf-b")
(fn [c]
(println "completing mf-b")
(c (* 2 x))))
(defn mf-c [x]
(println "starting mf-c")
(fn [c]
(println "completing mf-c")
(c (dec x))))
(def fn8 (m-chain [mf-a mf-b mf-c]))
(Now I'm aware that all monads are continuations in a sense - I'm going to put that aside for now. If I have made a grave mistake - please help me out so I can correct the question).
I'm trying to wrap my head around this Scala code above. I'm trying to work out if it is based on Maybe or on Continuations.
My question is: Can we understanding the error monad in terms of the Maybe monad or the Continuation monad?