diff --git a/hw_04/pom.xml b/hw_04/pom.xml new file mode 100644 index 0000000..3763593 --- /dev/null +++ b/hw_04/pom.xml @@ -0,0 +1,25 @@ + + 4.0.0 + + 2 + hw_04 + 0.0.1-SNAPSHOT + jar + + hw_04 + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + diff --git a/hw_04/src/main/java/hw_04/Collections.java b/hw_04/src/main/java/hw_04/Collections.java new file mode 100644 index 0000000..65598d9 --- /dev/null +++ b/hw_04/src/main/java/hw_04/Collections.java @@ -0,0 +1,57 @@ +package hw_04; + +import java.util.*; + +public class Collections { + public static List map(Function1 f, Iterable a) { + ArrayList res = new ArrayList(); + for (A i : a) { + res.add(f.apply(i)); + } + return res; + } + + public static List filter(Predicate p, Iterable a) { + ArrayList res = new ArrayList(); + for (A i : a) { + if (p.test(i)) { + res.add(i); + } + } + return res; + } + + public static List takeWhile(Predicate p, Iterable a) { + ArrayList res = new ArrayList(); + for (A i : a) { + if (!p.test(i)) { + return res; + } + res.add(i); + } + return res; + } + + public static List takeUnless(Predicate p, Iterable a) { + return takeWhile(p.not(), a); + } + + private static R foldr(Function2 f, R ini, Iterator iter) { + if (!iter.hasNext()) { + return ini; + } + return f.apply(iter.next(), foldr(f, ini, iter)); + } + + public static R foldr(Function2 f, R ini, Collection col) { + return foldr(f, ini, col.iterator()); + } + + public static R foldl(Function2 f, R ini, Collection col) { + Iterator iter = col.iterator(); + while (iter.hasNext()) { + ini = f.apply(ini, iter.next()); + } + return ini; + } +} diff --git a/hw_04/src/main/java/hw_04/Function1.java b/hw_04/src/main/java/hw_04/Function1.java new file mode 100644 index 0000000..2069910 --- /dev/null +++ b/hw_04/src/main/java/hw_04/Function1.java @@ -0,0 +1,15 @@ +package hw_04; + +public interface Function1 { + R apply(A1 arg); + + default Function1 compose(Function1 g) { + return new Function1() { + + @Override + public Rg apply(Acomp arg) { + return g.apply(Function1.this.apply(arg)); + } + }; + } +} diff --git a/hw_04/src/main/java/hw_04/Function2.java b/hw_04/src/main/java/hw_04/Function2.java new file mode 100644 index 0000000..265c5cc --- /dev/null +++ b/hw_04/src/main/java/hw_04/Function2.java @@ -0,0 +1,48 @@ +package hw_04; + +public abstract class Function2 { + public abstract R apply(A1 arg1, A2 arg2); + + public + Function2 compose(Function1 g) { + return new Function2() { + + @Override + public Rg apply(A1comp arg1, A2comp arg2) { + return g.apply(Function2.this.apply(arg1, arg2)); + } + + }; + } + + public Function1 bind1(A1 arg1) { + return new Function1() { + + @Override + public R apply(A2 arg) { + return Function2.this.apply(arg1, arg); + } + }; + } + + public Function1 bind2(A2 arg2) { + return new Function1() { + + @Override + public R apply(A1 arg) { + return Function2.this.apply(arg, arg2); + } + }; + } + + public Function1, A1> curry() { + return new Function1, A1>() { + + @Override + public Function1 apply(A1 arg) { + return Function2.this.bind1(arg); + } + + }; + } +} diff --git a/hw_04/src/main/java/hw_04/Predicate.java b/hw_04/src/main/java/hw_04/Predicate.java new file mode 100644 index 0000000..30a0e19 --- /dev/null +++ b/hw_04/src/main/java/hw_04/Predicate.java @@ -0,0 +1,50 @@ +package hw_04; + +public abstract class Predicate { + public static final Predicate ALWAYS_TRUE = new Predicate() { + + @Override + public boolean test(Object arg) { + return true; + } + + }; + + public static final Predicate ALWAYS_FALSE = new Predicate() { + + @Override + public boolean test(Object arg) { + return false; + } + + }; + + abstract public boolean test(A1 arg); + + public Predicate or(Predicate other) { + return new Predicate() { + @Override + public boolean test(T arg) { + return Predicate.this.test(arg) || other.test(arg); + } + }; + } + + public Predicate and(Predicate other) { + return new Predicate() { + @Override + public boolean test(T arg) { + return Predicate.this.test(arg) && other.test(arg); + } + }; + } + + public Predicate not() { + return new Predicate() { + @Override + public boolean test(A1 arg) { + return !Predicate.this.test(arg); + } + }; + } +} diff --git a/hw_04/src/test/java/hw_04/HomeworkTest.java b/hw_04/src/test/java/hw_04/HomeworkTest.java new file mode 100644 index 0000000..ceedbf7 --- /dev/null +++ b/hw_04/src/test/java/hw_04/HomeworkTest.java @@ -0,0 +1,232 @@ +package hw_04; + +import junit.framework.TestCase; +import java.util.*; + +import hw_04.HomeworkTest.C0; +import hw_04.HomeworkTest.C1; +import hw_04.HomeworkTest.D0; +import hw_04.HomeworkTest.D1; +import hw_04.HomeworkTest.D2; + +public class HomeworkTest extends TestCase { + final static Function1 fPlus3_5 = new Function1() { + + @Override + public Double apply(Double arg) { + return arg + 3.5; + } + }; + + + final static Function1 fDiv2_0 = new Function1() { + + @Override + public Double apply(Integer arg) { + return arg / 2.0; + } + }; + + final static Function1 length = new Function1() { + + @Override + public Integer apply(String arg) { + // TODO Auto-generated method stub + return arg.length(); + } + }; + + final static Function2 addChar = + new Function2() { + + @Override + public String apply(Character arg1, String arg2) { + return arg1 + arg2; + } + }; + + final static Predicate isEven = new Predicate() { + + @Override + public boolean test(Integer arg) { + return arg % 2 == 0; + } + }; + + final static Predicate failer = new Predicate() { + + @Override + public boolean test(Integer arg) { + // TODO Auto-generated method stub + int a = 3 / 0; + return false; + } + }; + + static class D0 { + public boolean b = true; + } + + static class D1 extends D0 {} + static class D2 extends D1 {} + static class D3 extends D2 {} + + class C0 {} + class C1 extends C0 {} + class C2 extends C1 {} + + public void testFunction1() { + assertEquals(6.0, fDiv2_0.compose(fPlus3_5).apply(5)); + } + + public void testFunction2Apply() { + assertEquals("abc", addChar.apply('a', "bc")); + } + + public void testFunction2Compose() { + assertEquals((Integer) 5, addChar.compose(length).apply('k', "abcd")); + } + + public void testFunction2Bind1() { + assertEquals("abc", addChar.bind1('a').apply("bc")); + } + + public void testFunction2Bind2() { + assertEquals("abc", addChar.bind2("bc").apply('a')); + } + + public void testFunction2Curry() { + assertEquals("abcd", addChar.curry().apply('a').apply("bcd")); + } + + public void testFunctionsInheritance() { + Function1 g = null; + + Function1 f = new Function1() { + + @Override + public D2 apply(C0 arg) { + // TODO Auto-generated method stub + return null; + } + }; + Function1 fg = f.compose(g); + + Function2 f2 = new Function2() { + + @Override + public D2 apply(C0 arg1, C1 arg2) { + // TODO Auto-generated method stub + return null; + } + }; + + Function2 f2g = f2.compose(g); + + } + + public void testPredicateBasic() { + assertTrue(Predicate.ALWAYS_TRUE.test(new Object())); + assertFalse(Predicate.ALWAYS_FALSE.test(null)); + + assertTrue(isEven.test(2)); + assertFalse(isEven.test(3)); + } + + public void testPredicateOrAndNot() { + assertTrue(Predicate.ALWAYS_TRUE.or(isEven).test(3)); + assertFalse(isEven.and(Predicate.ALWAYS_FALSE).test(2)); + assertTrue(Predicate.ALWAYS_FALSE.not().test(null)); + } + + public void testPredicateLazyness() { + assertTrue(Predicate.ALWAYS_TRUE.or(failer).test(null)); + assertFalse(Predicate.ALWAYS_FALSE.and(failer).test(null)); + } + + public void testPredicatesInheritance() { + Predicate pd0 = new Predicate() { + + @Override + public boolean test(D0 arg) { + // TODO Auto-generated method stub + return false; + } + }; + + Predicate pd1 = new Predicate() { + + @Override + public boolean test(D1 arg) { + // TODO Auto-generated method stub + return true; + } + }; + + Predicate pd2 = pd0.and(pd1); + } + + public void testCollectionsMap() { + assertEquals(Arrays.asList(0.5, 1.0, 1.5), Collections.map(fDiv2_0, Arrays.asList(1,2,3))); + } + + public void testCollectionsFilter() { + assertEquals(Arrays.asList(2,4), Collections.filter(isEven, Arrays.asList(1,2,3,4,5))); + assertEquals(new ArrayList(), Collections.filter(Predicate.ALWAYS_FALSE, Arrays.asList(1,2,3,4,5))); + + } + + public void testTakeWhile() { + assertEquals(Arrays.asList(1,3), Collections.takeWhile(isEven.not(), Arrays.asList(1,3,4,5))); + assertEquals(Arrays.asList(1,3,4,5), Collections.takeWhile(Predicate.ALWAYS_TRUE, Arrays.asList(1,3,4,5))); + } + + public void testTakeUnless() { + assertEquals(Arrays.asList(1,3), Collections.takeUnless(isEven, Arrays.asList(1,3,4,5))); + } + + public void testFoldr() { + assertEquals("abcd", Collections.foldr(addChar, "", Arrays.asList('a', 'b', 'c', 'd'))); + } + + public void testFoldl() { + assertEquals("abcd", Collections.foldl( + new Function2() { + @Override + public String apply(String arg1, Character arg2) { + return arg1 + arg2; + } + + } + , "", Arrays.asList('a', 'b', 'c', 'd'))); + } + + public void testCollectionsInheritance() { + List id0 = Collections.map(new Function1(){ + + @Override + public D1 apply(D2 arg) { + // TODO Auto-generated method stub + return null; + }}, Arrays.asList(new D2(), new D3())); + + id0 = Collections.filter(new Predicate() { + + @Override + public boolean test(D2 arg) { + // TODO Auto-generated method stub + return false; + } + }, Arrays.asList(new D2(), new D3())); + + D0 foldResD0 = Collections.foldr(new Function2() { + + @Override + public D1 apply(C1 arg1, D1 arg2) { + // TODO Auto-generated method stub + return null; + } + + }, new D1(), Arrays.asList(new C1())); + } +}