-
Notifications
You must be signed in to change notification settings - Fork 2
Option Monad
Dinko Srkoč edited this page Aug 7, 2011
·
4 revisions
Option represents optional values. Instances are either an instance of Some or an
instance of None. If None is the result of evaluating takeFrom closure, the entire
foreach expression results in None. This allows for chaining of Option values
without having to check for the existence of a value.
import static hr.helix.monadologie.MonadComprehension.foreach
import static hr.helix.monadologie.monads.Option.some
import static hr.helix.monadologie.monads.Option.none
def safe(Closure action) {
try {
some(action())
} catch (ignore) {
none()
}
}
def check = { name -> name ? some(name) : none() }
def load = { name -> safe { new File(name).text }},
parse = { text -> safe { text.tokenize()*.toInteger() }},
div = { a, b -> safe { a / b }}
def calc = { fileName ->
foreach {
file = takeFrom { check fileName }
text = takeFrom { load file }
data = takeFrom { parse text }
res = takeFrom { div data }
yield { res }
}
}
assert calc(null) == none() // file name validation failed
assert calc("foo.txt") == none() // file not found
def fileName = "/tmp/data"
new File(fileName).withWriter { w -> w << "aa bb" }
assert calc(fileName) == none() // number format exception
new File(fileName).withWriter { w -> w << "1 0" }
assert calc(fileName) == none() // division by zero
new File(fileName).withWriter { w -> w << "10 20" }
assert calc(fileName) == some(0.5)