Groovy Goodness: Add Some Curry for Taste
Currying is a technique to create a clone of a closure and fixing values for some of the parameters. We can fix one or more parameters, depending on the number of arguments we use for the curry()
method. The parameters are bound from left to right. The good thing is we can even use other closures as parameters for the curry()
method.
Let's see some curry()
action in the following sample:
00.
// Simple sample.
01.
def
addNumbers = { x, y -> x + y }
02.
def
addOne = addNumbers.curry(
1
)
03.
assert
5
== addOne(
4
)
04.
05.
06.
// General closure to use a filter on a list.
07.
def
filterList = { filter, list -> list.
findAll
(filter) }
08.
// Closure to find even numbers.
09.
def
even = { it %
2
==
0
}
10.
// Closure to find odd numbers.
11.
def
odd = { !even(it) }
12.
// Other closures can be curry parameters.
13.
def
evenFilterList = filterList.curry(even)
14.
def
oddFilterList = filterList.curry(odd)
15.
assert
[
0
,
2
,
4
,
6
,
8
] == evenFilterList(
0
..
8
)
16.
assert
[
1
,
3
,
5
,
7
] == oddFilterList(
0
..
8
)
17.
18.
19.
// Recipe to find text in lines.
20.
def
findText = { filter, handler, text ->
21.
text.
eachLine
{
22.
filter(it) ? handler(it) :
null
23.
}
24.
}
25.
// Recipe for a regular expression filter.
26.
def
regexFilter = { pattern, line -> line =~ pattern }
27.
28.
// Create filter for searching lines with "Groovy".
29.
def
groovyFilter = regexFilter.curry(/Groovy/)
30.
// Create handler to print out line.
31.
def
printHandler = {
println
"Found in line: $it"
}
32.
33.
// Create specific closure as clone of processText to
34.
// search with groovyFilter and print out found lines.
35.
def
findGroovy = findText.curry(groovyFilter, printHandler)
36.
37.
// Invoke the closure.
38.
findGroovy(
''
'Groovy rules!
39.
And Java?
40.
Well... Groovy needs the JVM...
41.
''
')
42.
43.
// This will output:
44.
// Found in line: Groovy rules!
45.
// Foudn in line: Well... Groovy needs the JVM...
Run this script on GroovyConsole.