-
Notifications
You must be signed in to change notification settings - Fork 2
Foreach Expansion
Dinko Srkoč edited this page Aug 7, 2011
·
6 revisions
Monad comprehension is just a convenient notation, a helpful and more readable way of expressing nested iterations and function application. In a way it's just a syntax sugar, not unlike that of Java 1.5 for-each loop.
foreach expressions are expressed in terms of three functions: bind, fmap, and filter.
The examples of the translation scheme are given below.
foreach {
x = takeFrom { expr1 }
yield { expr2 }
}where x is a variable, expands to
expr1.fmap { x -> expr2 }foreach {
x = takeFrom { expr1 }
guard { expr2 }
yield { expr3 }
}expands to
expr1.filter { x -> expr2 }.map { x -> expr3 }Note: guards are not yet implemented for all monads
foreach {
x = takeFrom { expr1 }
y = takeFrom { expr2 }
z = takeFrom { expr3 }
yield { expr4 }
}expands to
expr1.bind { x ->
expr2.bind { y ->
expr3.fmap { z -> expr4 }
}
}If we take Groovy List as being a monad, than the above mentioned functions might be
implemented like this:
List.metaClass.bind = { Closure fn ->
delegate.inject([]) { acc, elem -> acc + fn(elem) }
}where closure fn must return a list.
List.metaClass.fmap = { Closure fn ->
delegate.collect(fn)
}fmap is just a collect under disguise.
List.metaClass.filter = { Closure fn ->
delegate.findAll(fn)
}filter is just a renamed findAll.