Here are my implementations of some higher-order functions in java, foldl
, foldr
, map
and others.
Functionals.java
package org.adrianwalker.functional; import java.util.ArrayList; import java.util.Collections; import java.util.List; public final class Functionals { private static final String EMPTY_STRING = ""; private static final List EMPTY_LIST = Collections.EMPTY_LIST; private Functionals() { } public static <T1, T2> T2 foldr(final Function<T1, T2> f, final T2 b, final List<T1> lst) { if (lst.isEmpty()) { return b; } return f.call(head(lst), foldr(f, b, tail(lst))); } public static <T1, T2> T2 foldl(final Function<T1, T2> f, final T2 b, final List<T1> lst) { if (lst.isEmpty()) { return b; } return foldl(f, f.call(head(lst), b), tail(lst)); } public static <T1, T2> List<T2> map(final Function<T1, T2> f, final List<T1> lst) { return foldr(new Function<T1, List<T2>>() { @Override public List<T2> call(final T1 t1, final List<T2> t2) { return cons(f.call(t1), t2); } }, (List<T2>) EMPTY_LIST, lst); } public static <T1> List<T1> cons(final T1 x, final List<T1> xs) { List<T1> lst = newList(xs.size() + 1); lst.add(0, x); lst.addAll(1, xs); return Collections.unmodifiableList(lst); } public static <T1> T1 head(final List<T1> lst) { return lst.get(0); } public static <T1> List<T1> tail(final List<T1> lst) { List<T1> xs = newList(lst.size() - 1); xs.addAll(0, lst.subList(1, lst.size())); return Collections.unmodifiableList(xs); } public static List<Character> explode(final String string) { if (string.isEmpty()) { return (List<Character>) EMPTY_LIST; } return cons(string.charAt(0), explode(string.substring(1))); } public static String implode(final List<Character> lst) { return foldl(new Function<Character, String>() { @Override public String call(final Character t1, final String t2) { return t2 + t1; } }, EMPTY_STRING, lst); } public static <T1> List<T1> rev(final List<T1> lst) { return foldl(new Function<T1, List<T1>>() { @Override public List<T1> call(final T1 t1, final List<T1> t2) { return cons(t1, t2); } }, (List<T1>) EMPTY_LIST, lst); } private static <E> List<E> newList(final int initialCapacity) { return new ArrayList<E>(initialCapacity); } }
Example Usage
Summing a list of integers using foldr
.
List<Integer> input = Arrays.asList(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); Integer output = Functionals.foldr(new Function<Integer, Integer>() { @Override public Integer call(final Integer t1, final Integer t2) { return t1 + t2; } }, 0, input); System.out.println(String.format("Sum: %s", output));
Source Code
Download the source and see the unit tests for other examples of usage.
- Java Maven Project - functionals.zip