├── .gitignore
├── LICENSE.txt
├── README.md
├── pom.xml
└── src
├── main
└── java
│ └── uk
│ └── co
│ └── benjiweber
│ └── expressions
│ ├── Action.java
│ ├── ActionWithOneParam.java
│ ├── Block.java
│ ├── ChainableVoid.java
│ ├── Coalesce.java
│ ├── Curry.java
│ ├── EqualsHashcode.java
│ ├── InstanceOf.java
│ ├── InstanceOfMethodReference.java
│ ├── NullSafe.java
│ ├── Print.java
│ ├── Times.java
│ ├── ToString.java
│ ├── Try.java
│ ├── Using.java
│ ├── Value.java
│ ├── caseclass
│ ├── Case.java
│ ├── Case2.java
│ ├── Case3.java
│ ├── MatchExample.java
│ ├── MatchesAny.java
│ ├── ShapeExample.java
│ └── constructor
│ ├── collections
│ ├── EnhancedList.java
│ ├── ForwardingList.java
│ └── WithIndex.java
│ ├── exceptions
│ ├── Exceptions.java
│ ├── OrElse.java
│ ├── Result.java
│ └── WrapBuilder.java
│ ├── functions
│ ├── ExceptionalBiConsumer.java
│ ├── ExceptionalBiFunction.java
│ ├── ExceptionalConsumer.java
│ ├── ExceptionalFunction.java
│ ├── ExceptionalQuadConsumer.java
│ ├── ExceptionalQuadFunction.java
│ ├── ExceptionalQuinConsumer.java
│ ├── ExceptionalQuinFunction.java
│ ├── ExceptionalSexConsumer.java
│ ├── ExceptionalSexFunction.java
│ ├── ExceptionalSupplier.java
│ ├── ExceptionalTriConsumer.java
│ ├── ExceptionalTriFunction.java
│ ├── ExceptionalVoid.java
│ ├── QuadConsumer.java
│ ├── QuadFunction.java
│ ├── QuinConsumer.java
│ ├── QuinFunction.java
│ ├── SexConsumer.java
│ ├── SexFunction.java
│ ├── TriConsumer.java
│ └── TriFunction.java
│ ├── properties
│ ├── ExplicitName.java
│ ├── GuessesName.java
│ ├── Named.java
│ ├── Property.java
│ ├── Readonly.java
│ └── Writeonly.java
│ └── tuples
│ ├── BiTuple.java
│ ├── QuadTuple.java
│ ├── QuinTuple.java
│ ├── SexTuple.java
│ ├── TriTuple.java
│ ├── Tuple.java
│ └── UniTuple.java
└── test
└── java
└── uk
└── co
└── benjiweber
└── expressions
├── ChainableVoidTest.java
├── CoalesceTest.java
├── CurryTest.java
├── InstanceOfTest.java
├── NullSafeTest.java
├── OptionalFromExceptionalTest.java
├── Paint.java
├── PropertyTest.java
├── TimesTest.java
├── TryAsExpressionTest.java
├── UsingTest.java
├── caseclass
├── CaseConstructorTest.java
├── CaseListTest.java
├── CaseParseArgumentsTest.java
├── CaseSomeNoneTest.java
├── CaseTest.java
├── CaseTreeTest.java
├── DecompositionConstructorReferenceTest.java
├── DecompositionTest.java
├── NestedDecompositionTest.java
└── UnreadableDecompositionTest.java
├── collections
└── IndexedListTest.java
├── exceptions
├── Example.java
└── ExceptionsTest.java
├── functions
└── ExceptionalFunctionTest.java
└── tuples
└── TupleTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | *.class
3 | *.iml
4 | .idea/
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Benjamin Weber
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | expressions
2 | ===========
3 |
4 | Playing with Java8. Here's Try as an Expression. [More Examples](https://github.com/benjiman/expressions/blob/master/src/test/java/uk/co/benjiweber/expressions/TryAsExpressionTest.java)
5 | ```java
6 | @Test public void should_return_try_value() {
7 | String result = Try(() -> {
8 | return "try";
9 | }).Catch(NullPointerException.class, e -> {
10 | return "catch";
11 | }).apply();
12 |
13 | assertEquals("try", result);
14 | }
15 | ```
16 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | uk.co.benjiweber
8 | expressions
9 | 1.0-SNAPSHOT
10 |
11 |
12 |
13 |
14 | org.apache.maven.plugins
15 | maven-compiler-plugin
16 | 3.1
17 |
18 | 1.8
19 | 1.8
20 |
21 |
22 |
23 |
24 |
25 |
26 | junit
27 | junit
28 | 4.11
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/Action.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | public interface Action {
4 | public T apply() throws Exception;
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/ActionWithOneParam.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | public interface ActionWithOneParam {
4 | T apply(U param) throws Exception;
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/Block.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | public interface Block {
4 | public void apply() throws Exception;
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/ChainableVoid.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | import static uk.co.benjiweber.expressions.exceptions.Exceptions.unchecked;
4 |
5 | public class ChainableVoid {
6 | private final T obj;
7 |
8 | public ChainableVoid(T obj) {
9 | this.obj = obj;
10 | }
11 |
12 | public static ChainableVoid chain(T instance) {
13 | return new ChainableVoid<>(instance);
14 | }
15 |
16 | public ChainableVoid invoke(VoidMethodOn voidMethod) {
17 | unchecked(() -> voidMethod.invoke(obj));
18 | return this;
19 | }
20 |
21 | public ChainableVoid invoke(VoidMethodOneArgOn method, U value) {
22 | unchecked(() -> method.invoke(obj, value));
23 | return this;
24 | }
25 |
26 | public ChainableVoid invoke(VoidMethodTwoArgOn method, U value1, V value2) {
27 | unchecked(() -> method.invoke(obj, value1, value2));
28 | return this;
29 | }
30 |
31 | public interface VoidMethodOn {
32 | void invoke(T instance) throws Exception;
33 | }
34 |
35 | public interface VoidMethodOneArgOn {
36 | void invoke(T instance, U value) throws Exception;
37 | }
38 |
39 | public interface VoidMethodTwoArgOn {
40 | void invoke(T instance, U value1, V value2) throws Exception;
41 | }
42 |
43 | public T unwrap() {
44 | return obj;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/Coalesce.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | import java.util.Optional;
4 | import java.util.function.Supplier;
5 |
6 | import static java.util.Arrays.asList;
7 |
8 | public class Coalesce {
9 |
10 | public static T coalesce(Supplier... ts) {
11 | return asList(ts)
12 | .stream()
13 | .map(t -> t.get())
14 | .filter(t -> t != null)
15 | .findFirst()
16 | .orElse(null);
17 | }
18 |
19 | public interface AnotherSupplier extends Supplier {}
20 |
21 | public static Optional coalesce(AnotherSupplier>... ts) {
22 | return asList(ts)
23 | .stream()
24 | .map(t -> t.get())
25 | .filter(t -> t.isPresent())
26 | .findFirst()
27 | .orElse(Optional.empty());
28 | }
29 |
30 | public static Optional coalesce(Optional... ts) {
31 | return asList(ts)
32 | .stream()
33 | .filter(t -> t.isPresent())
34 | .findFirst()
35 | .orElse(Optional.empty());
36 | }
37 |
38 | public static T coalesce(T... ts) {
39 | return asList(ts)
40 | .stream()
41 | .filter(t -> t != null)
42 | .findFirst()
43 | .orElse(null);
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/Curry.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | import java.util.function.BiFunction;
4 | import java.util.function.Function;
5 |
6 | public class Curry {
7 |
8 | public static Function> curry(BiFunction fun) {
9 | return t -> u -> fun.apply(t,u);
10 | }
11 |
12 | public interface TriFunction {
13 | R apply(T t, U u, V v);
14 | }
15 |
16 | public static Function>> curry(TriFunction fun) {
17 | return t -> u -> v -> fun.apply(t,u,v);
18 | }
19 |
20 | public interface QuadFunction {
21 | R apply(T t, U u, V v, W w);
22 | }
23 |
24 | public static Function>>> curry(QuadFunction fun) {
25 | return t -> u -> v -> w -> fun.apply(t,u,v,w);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/EqualsHashcode.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | import java.util.List;
4 | import java.util.Objects;
5 | import java.util.function.Consumer;
6 | import java.util.function.Function;
7 |
8 | public interface EqualsHashcode {
9 | default boolean autoEquals(Object o) {
10 | if (this == o) return true;
11 | if (o == null || getClass() != o.getClass()) return false;
12 | final T value = (T)o;
13 | return props().stream()
14 | .allMatch(prop -> Objects.equals(prop.apply((T) this), prop.apply(value)));
15 | }
16 |
17 | default int autoHashCode() {
18 | return props().stream()
19 | .map(prop -> (Object)prop.apply((T)this))
20 | .collect(ResultCalculator::new, ResultCalculator::accept, ResultCalculator::combine)
21 | .result;
22 | }
23 |
24 |
25 | static class ResultCalculator implements Consumer {
26 | private int result = 0;
27 | public void accept(Object value) {
28 | result = 31 * result + (value != null ? value.hashCode() : 0);
29 | }
30 | public void combine(ResultCalculator other) {
31 | result += other.result;
32 | }
33 | }
34 |
35 | List> props();
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/InstanceOf.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | import java.util.Optional;
4 |
5 | public class InstanceOf {
6 |
7 | public static InstanceOfBuilder when(final Object obj) {
8 | return new InstanceOfBuilder() {
9 | public ThenBuilder instanceOf(final Class cls) {
10 | return new ThenBuilder() {
11 | public ElseBuilder then(ActionWithOneParam ifAction) {
12 | return new ElseBuilder(){
13 | public U otherwise(U value) {
14 | try {
15 | return cls.isInstance(obj) ? ifAction.apply((T)obj) : value;
16 | } catch (RuntimeException | Error e) {
17 | throw e;
18 | } catch (Exception e) {
19 | throw new RuntimeException( e);
20 | }
21 | }
22 |
23 | public Optional optional() {
24 | try {
25 | return cls.isInstance(obj) ? Optional.of(ifAction.apply((T) obj)) : Optional.empty();
26 | } catch (RuntimeException | Error e) {
27 | throw e;
28 | } catch (Exception e) {
29 | throw new RuntimeException(e);
30 | }
31 | }
32 | };
33 | }
34 | };
35 | }
36 | };
37 | }
38 |
39 | public interface InstanceOfBuilder {
40 | ThenBuilder instanceOf(Class cls);
41 | }
42 |
43 | public interface ThenBuilder {
44 | ElseBuilder then(ActionWithOneParam action);
45 | }
46 |
47 | public interface ElseBuilder {
48 | U otherwise(U value);
49 | Optional optional();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/InstanceOfMethodReference.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | public class InstanceOfMethodReference {
4 |
5 | public static void main(String... args) throws Exception {
6 | Object foo = "curry_and_partially_apply";
7 | Object bar = 5;
8 | Integer result =
9 | when(foo)
10 | .is(String.class)
11 | .then(String::compareTo).apply("other");
12 |
13 | System.out.println(result);
14 | }
15 |
16 | interface NoArg {
17 | U apply(T instance);
18 | }
19 |
20 | interface OneArg {
21 | U apply(T instance, ARG1 arg1);
22 | }
23 |
24 | static class OneArgApplicator {
25 | private final OneArg action;
26 | private final I instance;
27 |
28 | OneArgApplicator(OneArg action, I instance) {
29 | this.action = action;
30 | this.instance = instance;
31 | }
32 |
33 | public R apply(ARG1 arg1) {
34 | return action.apply(instance, arg1);
35 | }
36 | }
37 |
38 | static interface When {
39 | public Is is(Class cls);
40 | }
41 |
42 | static class Is {
43 |
44 | private T instance;
45 |
46 | public Is(T instance) {
47 | this.instance = instance;
48 | }
49 |
50 | OneArgApplicator then(OneArg action) throws Exception {
51 | return new OneArgApplicator(action, instance);
52 | }
53 |
54 | }
55 |
56 | public static When when(final Object input) {
57 | return new When() {
58 | public Is is(Class cls) {
59 | return new Is((T)input);
60 | }
61 | };
62 | }
63 |
64 | public static OneArgApplicator then(T instance, OneArg action) throws Exception {
65 | return new OneArgApplicator(action, instance);
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/NullSafe.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | import java.util.Optional;
4 | import java.util.function.Supplier;
5 |
6 | public class NullSafe {
7 | public static Optional nullSafe(Supplier supplier) {
8 | try {
9 | return Optional.of(supplier.get());
10 | } catch (NullPointerException e) {
11 | return Optional.empty();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/Print.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | public class Print {
4 | public static T println(T t) {
5 | System.out.println(t);
6 | return t;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/Times.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | public class Times {
4 | public interface Action { void apply(); }
5 | public interface TimesBuilder { void invoke(Action action); }
6 |
7 | public static TimesBuilder times(int times) {
8 | return action -> {
9 | for (int i = 0; i < times; i++) {
10 | action.apply();
11 | }
12 | };
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/ToString.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | import java.util.List;
4 | import java.util.function.Function;
5 | import java.util.stream.Collectors;
6 |
7 | public interface ToString {
8 | default String autoToString() {
9 | return "{" +
10 | props().stream()
11 | .map(prop -> (Object)prop.apply((T)this))
12 | .map(prop -> prop == null ? "_" : prop.toString())
13 | .collect(Collectors.joining(", ")) +
14 | "}";
15 | }
16 |
17 | List> props();
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/Try.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | import java.util.LinkedHashMap;
4 | import java.util.Map;
5 |
6 | public class Try {
7 |
8 | public static TryBuilder Try(Action action) {
9 | return new TryBuilder<>(action);
10 | }
11 |
12 | static interface Catch {
13 | TryBuilder Catch(Class cls, ActionWithOneParam action);
14 | }
15 | static interface Finally {
16 | TryBuilder Finally(Block action);
17 | }
18 | public static class TryBuilder implements Catch, Finally {
19 |
20 | private Action mainAction;
21 |
22 | Map, ActionWithOneParam> catches = new LinkedHashMap<>();
23 | public Block finalAction;
24 |
25 | public TryBuilder(Action mainAction) {
26 |
27 | this.mainAction = mainAction;
28 | }
29 | public T apply() {
30 | try {
31 | return mainAction.apply();
32 | } catch (RuntimeException e) {
33 | return handle(e, ex -> {throw ex;});
34 | } catch (Error e) {
35 | return handle(e, ex -> {throw ex;});
36 | } catch (Exception e) {
37 | return handle(e, ex -> {throw new RuntimeException(ex);});
38 | } finally {
39 | if (finalAction != null) {
40 | try {
41 | finalAction.apply();
42 | } catch (RuntimeException e) {
43 | return handle(e, ex -> {throw ex;});
44 | } catch (Error e) {
45 | return handle(e, ex -> {throw ex;});
46 | } catch (Exception e) {
47 | return handle(e, ex -> {throw new RuntimeException(ex);});
48 | }
49 | }
50 | }
51 | }
52 |
53 | interface Thrower {
54 | T doThrow(E e) throws W;
55 | }
56 |
57 | private T handle(E e, Thrower thrower) throws W {
58 | for (Class extends Throwable> cls : catches.keySet()) {
59 | if (cls.isAssignableFrom(e.getClass())) {
60 | return runCatchBlock(catches.get(cls),e);
61 | }
62 | }
63 | return thrower.doThrow(e);
64 | }
65 |
66 | @SuppressWarnings("unchecked")
67 | public T runCatchBlock(ActionWithOneParam catchBlock, Throwable throwable) {
68 | try {
69 | return catchBlock.apply((U)throwable);
70 | } catch (Exception e) {
71 | throw new RuntimeException(e);
72 | }
73 | }
74 |
75 | public TryBuilder Finally(Block action) {
76 | this.finalAction = action;
77 | return this;
78 | }
79 |
80 | @Override
81 | public TryBuilder Catch(Class cls, ActionWithOneParam action) {
82 | ActionWithOneParam foo = action::apply;
83 | this.catches.put(cls, foo);
84 | return this;
85 | }
86 |
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/Using.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | import java.util.function.Function;
4 | import java.util.function.Supplier;
5 |
6 | public class Using {
7 | public static R using(Supplier closeableProvider, Function function) {
8 | try (T t = closeableProvider.get()) {
9 | return function.apply(t);
10 | } catch (RuntimeException | Error e) {
11 | throw e;
12 | } catch (Exception e) {
13 | throw new RuntimeException(e);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/Value.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 | import java.util.function.Function;
6 |
7 | public class Value implements EqualsHashcode, ToString {
8 | private List> props;
9 |
10 | @Override
11 | public boolean equals(Object other) {
12 | return autoEquals(other);
13 | }
14 |
15 | @Override
16 | public int hashCode() {
17 | return autoHashCode();
18 | }
19 |
20 | @Override
21 | public String toString() {
22 | return autoToString();
23 | }
24 |
25 | public List> props() {
26 | return props;
27 | }
28 |
29 | public T using(Function... props) {
30 | this.props = Arrays.asList(props);
31 | return (T) this;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/uk/co/benjiweber/expressions/caseclass/Case.java:
--------------------------------------------------------------------------------
1 | package uk.co.benjiweber.expressions.caseclass;
2 |
3 | import uk.co.benjiweber.expressions.EqualsHashcode;
4 | import uk.co.benjiweber.expressions.caseclass.constructor.references.BiMatch;
5 | import uk.co.benjiweber.expressions.caseclass.constructor.references.TriMatch;
6 | import uk.co.benjiweber.expressions.caseclass.constructor.references.UniMatch;
7 | import uk.co.benjiweber.expressions.functions.TriFunction;
8 |
9 | import java.util.ArrayList;
10 | import java.util.List;
11 | import java.util.Optional;
12 | import java.util.function.BiFunction;
13 | import java.util.function.Function;
14 | import java.util.function.Predicate;
15 | import java.util.function.Supplier;
16 | import java.util.stream.Collectors;
17 | import java.util.stream.Stream;
18 |
19 | import static java.util.Arrays.asList;
20 |
21 | public interface Case extends EqualsHashcode {
22 | default MatchBuilder match() {
23 | return new MatchBuilder() {
24 | public MatchBuilderR when(T value, Function f) {
25 | return new MatchBuilderR(asList(MatchDefinition.create(value, f)), Case.this);
26 | }
27 | public MatchBuilderR when(TwoMissing value, BiFunction f) {
28 | Function valueExtractor = t -> f.apply(value.prop1((T)Case.this), value.prop2((T)Case.this));
29 | return new MatchBuilderR(asList(MatchDefinition.create(value.original(), valueExtractor)), Case.this);
30 | }
31 |
32 | public ZeroMatchConstructorBuilder when(Supplier constructor) {
33 | return new ZeroMatchConstructorBuilder() {
34 | public MatchBuilderR then(Function f) {
35 | T original = constructor.get();
36 | return new MatchBuilderR(asList(MatchDefinition.create(original, f)), Case.this);
37 | }
38 | };
39 | }
40 |
41 | public ZeroMatchConstructorBuilder when(Function constructor, A a) {
42 | return new ZeroMatchConstructorBuilder() {
43 | public MatchBuilderR then(Function f) {
44 | T original = constructor.apply(a);
45 | return new MatchBuilderR(asList(MatchDefinition.create(original, f)), Case.this);
46 | }
47 | };
48 | }
49 |
50 | public UniMatchConstructorBuilder when(Function constructor, MatchesAny a) {
51 | return new UniMatchConstructorBuilder() {
52 | public MatchBuilderR then(Function f) {
53 | T original = constructor.apply(null);
54 | List