This assignment is a continuation of the previous one. You are to write the same library from Homework #2 but implement versions in Java and Standard ML. This assignment is due Thursday, October 23 for undergraduates, and Wednesday, October 22 for graduates.
Readings: Read as many on-line tutorials or book chapters on Java and ML as is reasonable without seriously impacting your personal life.
For this assignment, you will add at least the following files to your repository:
/homework/cmsi386/src/main/sml/ListUtil.sml /homework/cmsi386/src/main/sml/ListUtilTest.sml /homework/cmsi386/src/main/java/edu/lmu/cs/your_login_name/util/ListUtil.java /homework/cmsi386/src/test/java/edu/lmu/cs/your_login_name/util/ListUtilTest.java
The libraries for this assignment will be built as follows:
As in the previous homework assignment, a few sample test cases will tell you how the methods should work (in some cases, at least). Note that in no way is this list anywhere near a complete set of test cases. You will be expected to submit a much richer set of test cases.
ML
Wrap up your six ML functions in a structure, something like this:
structure ListStuff = struct fun rotate ... fun right_reduce ... fun descending_integer_squares ... fun partial_filter ... fun flatten ... fun histogram ... end
I say "something like" because you may find it advantageous, as I did, to use local and val instead of fun in places.
ML doesn't really have a popular unit testing framework, so you'll want to write an assert method yourself:
assert (descending_integer_squares [4, 3, 2, 1, ~10] = [100, 16, 9, 4, 1]); assert (partial_filter op>= 7 [] = 0); assert (partial_filter op>= 7 [5, 8, 11, 20, 9, 1, 6, 10] = 3); assert (partial_filter op<= 30 [5, 8, 11, 20, 9, 1, 6, 10] = 0); assert (partial_filter op<= 19 [5, 8, 11, 20, 9, 1, 6, 10] = 1); assert (partial_filter op= 5 [5, 8, 11, 5, 9, 1, 6, 10] = 2); assert (histogram [4, 50, 6, 12, 4, 6, 12, 12, 12, 4] = [(4,3),(50,1),(6,2),(12,4)]); assert (rotate 0 [] = []); assert (rotate 7 [1, 2, 3, 4, 5, 6, 7, 8, 9] = [3, 4, 5, 6, 7, 8, 9, 1, 2]); assert (rotate 900007 [1, 2, 3, 4, 5, 6, 7, 8, 9] = [3, 4, 5, 6, 7, 8, 9, 1, 2]); assert (flatten [[1], [2, 3], [], [4, 5, 6, 7]] = [1, 2, 3, 4, 5, 6, 7]); assert (right_reduce op+ [4, 5, 6, 2] = 17); assert (right_reduce op- [4, 5, 6, 2] = 3);
Java
ListUtil.java should contain a utility class with a private constructor and the six methods all static. In the spirit of Java, we really should make all of the methods generic. In this case your class will look like this:
package ...
import ...
public class ListUtil {
public static interface BinaryPredicate<S, T> {
boolean evaluate(S x, T y);
}
public static interface BinaryFunction<S, T, U> {
U evaluate(S x, T y);
}
private ListUtil() {}
public static <S, T> int partialFilter(BinaryPredicate<S, T> p, S x, List<T> a) {...}
public static List<?> flatten(List<?> a) {...}
public static <T> Map<T, Integer> histogram(List<T> a) {...}
public static <T> List<T> rotate(int n, List<T> a) {...}
public static <T> T rightReduce(BinaryFunction<T, T, T> f, List<T> a) {...}
public static List<Integer> descendingIntegerSquares(List<Integer> a) {...}
}
If you prefer, you could deal entirely with Objects and see how your Java code plays out.
Since Java is the language most everyone already knows, I'll leave it to you to come up with a good test suite. You must use JUnit here; it is an industry de facto standard.