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 extends A> a) {
+ ArrayList res = new ArrayList();
+ for (A i : a) {
+ res.add(f.apply(i));
+ }
+ return res;
+ }
+
+ public static List filter(Predicate p, Iterable extends A> 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 extends A> 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 extends A> a) {
+ return takeWhile(p.not(), a);
+ }
+
+ private static R foldr(Function2 f, R ini, Iterator extends A> iter) {
+ if (!iter.hasNext()) {
+ return ini;
+ }
+ return f.apply(iter.next(), foldr(f, ini, iter));
+ }
+
+ public static R foldr(Function2 f, R ini, Collection extends A> col) {
+ return foldr(f, ini, col.iterator());
+ }
+
+ public static R foldl(Function2 f, R ini, Collection extends A> col) {
+ Iterator extends A> 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