diff --git a/combinator/README.md b/combinator/README.md
new file mode 100644
index 000000000..e22450321
--- /dev/null
+++ b/combinator/README.md
@@ -0,0 +1,33 @@
+---
+layout: pattern
+title: Combinator
+folder: combinator
+permalink: /patterns/combinator/
+categories: Behavioral
+tags:
+ - Functional
+ - Reactive
+ - Idiom
+---
+
+## Also known as
+Composition pattern
+
+## Intent
+The functional pattern representing a style of organizing libraries centered around the idea of combining functions.
+Putting it simply, there is some type T, some functions for constructing "primitive" values of type T,
+and some "combinators" which can combine values of type T in various ways to build up more complex values of type T.
+
+
+## Applicability
+Use the combinator pattern when:
+- You are able to create a more complex value from more plain values but having the same type(a combination of them)
+
+## Real world examples
+- java.util.function.Function#compose
+- java.util.function.Function#andThen
+
+## Credits
+- [Example for java](https://gtrefs.github.io/code/combinator-pattern/)
+- [Combinator pattern](https://wiki.haskell.org/Combinator_pattern)
+- [Combinatory logic](https://wiki.haskell.org/Combinatory_logic)
\ No newline at end of file
diff --git a/combinator/pom.xml b/combinator/pom.xml
new file mode 100644
index 000000000..3edfa7580
--- /dev/null
+++ b/combinator/pom.xml
@@ -0,0 +1,44 @@
+
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.23.0-SNAPSHOT
+
+
+ combinator
+
+
+ junit
+ junit
+ test
+
+
+
+
diff --git a/combinator/src/main/java/com/iluwatar/combinator/CombinatorApp.java b/combinator/src/main/java/com/iluwatar/combinator/CombinatorApp.java
new file mode 100644
index 000000000..578c87bfe
--- /dev/null
+++ b/combinator/src/main/java/com/iluwatar/combinator/CombinatorApp.java
@@ -0,0 +1,92 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.combinator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * The functional pattern representing a style of organizing libraries
+ * centered around the idea of combining functions.
+ * Putting it simply, there is some type T, some functions
+ * for constructing "primitive" values of type T,
+ * and some "combinators" which can combine values of type T
+ * in various ways to build up more complex values of type T.
+ * The class {@link Finder} defines a simple function {@link Finder#find(String)}
+ * and connected functions
+ * {@link Finder#or(Finder)},
+ * {@link Finder#not(Finder)},
+ * {@link Finder#and(Finder)}
+ * Using them the became possible to get more complex functions {@link Finders}
+ */
+public class CombinatorApp {
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOGGER = LoggerFactory.getLogger(CombinatorApp.class);
+
+ /**
+ * main.
+ * @param args args
+ */
+ public static void main(String[] args) {
+ var queriesOr = new String[]{"many", "Annabel"};
+ var finder = Finders.expandedFinder(queriesOr);
+ var res = finder.find(text());
+ LOGGER.info("the result of expanded(or) query[{}] is {}", queriesOr, res);
+
+ var queriesAnd = new String[]{"Annabel", "my"};
+ finder = Finders.specializedFinder(queriesAnd);
+ res = finder.find(text());
+ LOGGER.info("the result of specialized(and) query[{}] is {}", queriesAnd, res);
+
+ finder = Finders.advancedFinder("it was","kingdom","sea");
+ res = finder.find(text());
+ LOGGER.info("the result of advanced query is {}", res);
+
+ res = Finders.filteredFinder(" was ", "many", "child").find(text());
+ LOGGER.info("the result of filtered query is {}", res);
+
+
+ }
+
+ private static String text() {
+ return
+ "It was many and many a year ago,\n"
+ + "In a kingdom by the sea,\n"
+ + "That a maiden there lived whom you may know\n"
+ + "By the name of ANNABEL LEE;\n"
+ + "And this maiden she lived with no other thought\n"
+ + "Than to love and be loved by me.\n"
+ + "I was a child and she was a child,\n"
+ + "In this kingdom by the sea;\n"
+ + "But we loved with a love that was more than love-\n"
+ + "I and my Annabel Lee;\n"
+ + "With a love that the winged seraphs of heaven\n"
+ + "Coveted her and me.";
+ }
+
+}
diff --git a/combinator/src/main/java/com/iluwatar/combinator/Finder.java b/combinator/src/main/java/com/iluwatar/combinator/Finder.java
new file mode 100644
index 000000000..37cecbd0c
--- /dev/null
+++ b/combinator/src/main/java/com/iluwatar/combinator/Finder.java
@@ -0,0 +1,93 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.combinator;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Functional interface to find lines in text.
+ */
+public interface Finder {
+
+ /**
+ * The function to find lines in text.
+ * @param text full tet
+ * @return result of searching
+ */
+ List find(String text);
+
+ /**
+ * Simple implementation of function {@link #find(String)}.
+ * @param word for searching
+ * @return this
+ */
+ static Finder contains(String word) {
+ return txt -> Stream.of(txt.split("\n"))
+ .filter(line -> line.toLowerCase().contains(word.toLowerCase()))
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * combinator not.
+ * @param notFinder finder to combine
+ * @return new finder including previous finders
+ */
+ default Finder not(Finder notFinder) {
+ return txt -> {
+ List res = this.find(txt);
+ res.removeAll(notFinder.find(txt));
+ return res;
+ };
+ }
+
+ /**
+ * combinator or.
+ * @param orFinder finder to combine
+ * @return new finder including previous finders
+ */
+ default Finder or(Finder orFinder) {
+ return txt -> {
+ List res = this.find(txt);
+ res.addAll(orFinder.find(txt));
+ return res;
+ };
+ }
+
+ /**
+ * combinator or.
+ * @param andFinder finder to combine
+ * @return new finder including previous finders
+ */
+ default Finder and(Finder andFinder) {
+ return
+ txt -> this
+ .find(txt)
+ .stream()
+ .flatMap(line -> andFinder.find(line).stream())
+ .collect(Collectors.toList());
+ }
+
+}
diff --git a/combinator/src/main/java/com/iluwatar/combinator/Finders.java b/combinator/src/main/java/com/iluwatar/combinator/Finders.java
new file mode 100644
index 000000000..f91c07f4c
--- /dev/null
+++ b/combinator/src/main/java/com/iluwatar/combinator/Finders.java
@@ -0,0 +1,103 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.combinator;
+
+import java.util.ArrayList;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Complex finders consisting of simple finder.
+ */
+public class Finders {
+ private Finders() {
+ }
+
+
+ /**
+ * Finder to find a complex query.
+ * @param query to find
+ * @param orQuery alternative to find
+ * @param notQuery exclude from search
+ * @return new finder
+ */
+ public static Finder advancedFinder(String query, String orQuery, String notQuery) {
+ return
+ Finder.contains(query)
+ .or(Finder.contains(orQuery))
+ .not(Finder.contains(notQuery));
+ }
+
+ /**
+ * Filtered finder looking a query with excluded queries as well.
+ * @param query to find
+ * @param excludeQueries to exclude
+ * @return new finder
+ */
+ public static Finder filteredFinder(String query, String... excludeQueries) {
+ var finder = Finder.contains(query);
+
+ for (String q : excludeQueries) {
+ finder = finder.not(Finder.contains(q));
+ }
+ return finder;
+
+ }
+
+ /**
+ * Specialized query. Every next query is looked in previous result.
+ * @param queries array with queries
+ * @return new finder
+ */
+ public static Finder specializedFinder(String... queries) {
+ var finder = identMult();
+
+ for (String query : queries) {
+ finder = finder.and(Finder.contains(query));
+ }
+ return finder;
+ }
+
+ /**
+ * Expanded query. Looking for alternatives.
+ * @param queries array with queries.
+ * @return new finder
+ */
+ public static Finder expandedFinder(String... queries) {
+ var finder = identSum();
+
+ for (String query : queries) {
+ finder = finder.or(Finder.contains(query));
+ }
+ return finder;
+ }
+
+ private static Finder identMult() {
+ return txt -> Stream.of(txt.split("\n")).collect(Collectors.toList());
+ }
+
+ private static Finder identSum() {
+ return txt -> new ArrayList<>();
+ }
+}
diff --git a/combinator/src/test/java/com/iluwatar/combinator/CombinatorAppTest.java b/combinator/src/test/java/com/iluwatar/combinator/CombinatorAppTest.java
new file mode 100644
index 000000000..f42b46c14
--- /dev/null
+++ b/combinator/src/test/java/com/iluwatar/combinator/CombinatorAppTest.java
@@ -0,0 +1,36 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.combinator;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class CombinatorAppTest {
+
+ @Test
+ public void main() {
+ CombinatorApp.main(new String[]{});
+ }
+}
\ No newline at end of file
diff --git a/combinator/src/test/java/com/iluwatar/combinator/FinderTest.java b/combinator/src/test/java/com/iluwatar/combinator/FinderTest.java
new file mode 100644
index 000000000..67314903d
--- /dev/null
+++ b/combinator/src/test/java/com/iluwatar/combinator/FinderTest.java
@@ -0,0 +1,44 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.combinator;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class FinderTest {
+
+ @Test
+ public void contains() {
+ var example = "the first one \nthe second one \n";
+
+ var result = Finder.contains("second").find(example);
+ Assert.assertEquals(result.size(),1);
+ Assert.assertEquals(result.get(0),"the second one ");
+ }
+
+}
\ No newline at end of file
diff --git a/combinator/src/test/java/com/iluwatar/combinator/FindersTest.java b/combinator/src/test/java/com/iluwatar/combinator/FindersTest.java
new file mode 100644
index 000000000..5753ec92a
--- /dev/null
+++ b/combinator/src/test/java/com/iluwatar/combinator/FindersTest.java
@@ -0,0 +1,83 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2019 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.combinator;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.List;
+
+import static com.iluwatar.combinator.Finders.*;
+import static org.junit.Assert.*;
+
+public class FindersTest {
+
+ @Test
+ public void advancedFinderTest() {
+ var res = advancedFinder("it was","kingdom","sea").find(text());
+ Assert.assertEquals(res.size(),1);
+ Assert.assertEquals(res.get(0),"It was many and many a year ago,");
+ }
+
+ @Test
+ public void filteredFinderTest() {
+ var res = filteredFinder(" was ", "many", "child").find(text());
+ Assert.assertEquals(res.size(),1);
+ Assert.assertEquals(res.get(0),"But we loved with a love that was more than love-");
+ }
+
+ @Test
+ public void specializedFinderTest() {
+ var res = specializedFinder("love","heaven").find(text());
+ Assert.assertEquals(res.size(),1);
+ Assert.assertEquals(res.get(0),"With a love that the winged seraphs of heaven");
+ }
+
+ @Test
+ public void expandedFinderTest() {
+ var res = expandedFinder("It was","kingdom").find(text());
+ Assert.assertEquals(res.size(),3);
+ Assert.assertEquals(res.get(0),"It was many and many a year ago,");
+ Assert.assertEquals(res.get(1),"In a kingdom by the sea,");
+ Assert.assertEquals(res.get(2),"In this kingdom by the sea;");
+ }
+
+
+ private String text(){
+ return
+ "It was many and many a year ago,\n"
+ + "In a kingdom by the sea,\n"
+ + "That a maiden there lived whom you may know\n"
+ + "By the name of ANNABEL LEE;\n"
+ + "And this maiden she lived with no other thought\n"
+ + "Than to love and be loved by me.\n"
+ + "I was a child and she was a child,\n"
+ + "In this kingdom by the sea;\n"
+ + "But we loved with a love that was more than love-\n"
+ + "I and my Annabel Lee;\n"
+ + "With a love that the winged seraphs of heaven\n"
+ + "Coveted her and me.";
+ }
+
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 9ffaa8525..ba6655c3d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,18 +1,18 @@
-
circuit-breaker
role-object
saga
- double-buffer
- sharding
- game-loop
-
+ double-buffer
+ sharding
+ game-loop
+ combinator
+
-
-
- jitpack.io
- https://jitpack.io
-
-
+
+
+ jitpack.io
+ https://jitpack.io
+
+
@@ -387,7 +388,7 @@
jar-with-dependencies
-
${project.artifactId}
false
@@ -422,8 +423,8 @@
-
org.commonjava.maven.plugins