Let's go ahead and add general fold and reduce even though I've held off on
adding a function type to samskivert because everyone and their mother has a
function type. This is hopefully innocuous enough and allows you to obtain
generality at the expense of verbosity:
Folds.foldLeft(new Folds.R<Integer>() {
public Integer apply (Integer zero, Integer elem) {
return Math.max(zero, elem);
}
}, 0, values);
Folds.foldLeft(new Folds.R<String>() {
public String apply (String zero, String elem) {
return zero + elem;
}
}, "", strings);
Maybe by Java 8 or 9 we'll have closures and this can become:
Folds.foldLeft((Integer b, Integer a) => Math.max(b, a))
Folds.foldLeft((String b, String a) => b + a)
or maybe:
Folds.foldLeft(#(Integer b, Integer a) { return Math.max(b, a); })
Folds.foldLeft(#(String b, String a) { return b + a; })
who knows where the syntax bike shed arguments will end up. Of course, that'll
probably hit the shelves around 2015 or so at the rate Oracle seems to be
proceeding.
If you really want to get jiggy with the functional programming, you can check
out Functional Java, which goes the whole nine yards, but sort of ignores Java's
standard collections in the process which kind of sucks:
http://functionaljava.org/
git-svn-id: https://samskivert.googlecode.com/svn/trunk@2896 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -22,6 +22,7 @@ package com.samskivert.util;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -29,6 +30,42 @@ import java.util.Map;
|
||||
*/
|
||||
public class Folds
|
||||
{
|
||||
/** Used with {@link #foldLeft}. */
|
||||
public interface F<B,A>
|
||||
{
|
||||
/** Folds the supplied element into the result. */
|
||||
B apply (B zero, A elem);
|
||||
}
|
||||
|
||||
/** For reductions and same-typed folds. */
|
||||
public interface R<A> extends F<A,A> {}
|
||||
|
||||
/**
|
||||
* Left folds the supplied function over the supplied values using the supplied starting value.
|
||||
*/
|
||||
public static <A, B> B foldLeft (F<B,A> func, B zero, Iterable<? extends A> values)
|
||||
{
|
||||
for (A value : values) {
|
||||
zero = func.apply(zero, value);
|
||||
}
|
||||
return zero;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces the supplied values using the supplied function with a left fold.
|
||||
*
|
||||
* @exception NoSuchElementException thrown if values does not contain at least one element.
|
||||
*/
|
||||
public static <A> A reduceLeft (F<A,A> func, Iterable<? extends A> values)
|
||||
{
|
||||
Iterator<A> iter = values.iterator();
|
||||
A zero = iter.next();
|
||||
while (iter.hasNext()) {
|
||||
zero = func.apply(zero, iter.next());
|
||||
}
|
||||
return zero;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sums the supplied collection of numbers to an int with a left to right fold.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user