-
-
Save cybernetics/8e7e19f372e68de6f3a7ab88af495c19 to your computer and use it in GitHub Desktop.
Revisions
-
jbgi revised this gist
Jan 24, 2016 . 1 changed file with 11 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -53,13 +53,21 @@ public static Expression lazy(Supplier<Expression> expression) { return new Lazy(expression); } public static <R> Expression.Cases<R> cases(Function<Integer, R> Const, AddMapper<Expression, R> Add, MultMapper<Expression, R> Mult, Function<Expression, R> Neg) { return new LambdaCases<>(Const, Add, Mult, Neg); } public static <R> Function<Expression, R> cata(Function<Integer, R> Const, AddMapper<Supplier<R>, R> Add, MultMapper<Supplier<R>, R> Mult, Function<Supplier<R>, R> Neg) { Expression.Cases<R> cata = new Object() { Expression.Cases<R> cata = Expressions.cases( Const, (left, right) -> Add.Add(() -> left.match(this.cata), () -> right.match(this.cata)), (left, right) -> Mult.Mult(() -> left.match(this.cata), () -> right.match(this.cata)), (expr) -> Neg.apply(() -> expr.match(this.cata)) ); ; }.cata; return expression -> expression.match(cata); -
jbgi revised this gist
Dec 29, 2015 . 1 changed file with 131 additions and 51 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -33,7 +33,7 @@ public final class Expressions { private Expressions() { } public static Expression Const(int value) { return new Const(value); } @@ -53,10 +53,18 @@ public static Expression lazy(Supplier<Expression> expression) { return new Lazy(expression); } public static <R> Expression.Cases<R> cases(Function<Integer, R> Const, AddMapper<Expression, R> Add, MultMapper<Expression, R> Mult, Function<Expression, R> Neg) { return new LambdaCases<>(Const, Add, Mult, Neg); } public static <R> Function<Expression, R> cata(Function<Integer, R> Const, AddMapper<Supplier<R>, R> Add, MultMapper<Supplier<R>, R> Mult, Function<Supplier<R>, R> Neg) { Expression.Cases<R> cata = new Object() { Expression.Cases<R> cata = Expressions.cases(Const, (left, right) -> Add.Add(() -> left.match(this.cata), () -> right.match(this.cata)), (left, right) -> Mult.Mult(() -> left.match(this.cata), () -> right.match(this.cata)), (expr) -> Neg.apply(() -> expr.match(this.cata))); ; }.cata; return expression -> expression.match(cata); } public static Optional<Integer> getValue(Expression expression) { return expression.match(valueGetter); } @@ -126,9 +134,9 @@ public static TotalMatchBuilderConst cases() { } private static final class Const extends Expression { private final int value; Const(int value) { this.value = value; } @@ -214,41 +222,33 @@ public <R> R match(Expression.Cases<R> cases) { } } public interface AddMapper<R_, R> { R Add(R_ left, R_ right); } public interface MultMapper<R_, R> { R Mult(R_ left, R_ right); } private static final class LambdaCases<R> implements Expression.Cases<R> { private final Function<Integer, R> Const; private final AddMapper<Expression, R> Add; private final MultMapper<Expression, R> Mult; private final Function<Expression, R> Neg; LambdaCases(Function<Integer, R> Const, AddMapper<Expression, R> Add, MultMapper<Expression, R> Mult, Function<Expression, R> Neg) { this.Const = Const; this.Add = Add; this.Mult = Mult; this.Neg = Neg; } @Override public R Const(int value) { return this.Const.apply(value); } @Override @@ -263,126 +263,190 @@ public R Mult(Expression left, Expression right) { @Override public R Neg(Expression expr) { return this.Neg.apply(expr); } } public static final class TotalMatchBuilderConst { private TotalMatchBuilderConst() { } public final <R> TotalMatchBuilderAdd<R> Const(Function<Integer, R> Const) { return new TotalMatchBuilderAdd<>(Const); } public final <R> TotalMatchBuilderAdd<R> Const(R r) { return this.Const((value) -> r); } public final <R> PartialMatchBuilderMult<R> Add(AddMapper<Expression, R> Add) { return new PartialMatchBuilderMult<>(null, Add); } public final <R> PartialMatchBuilderMult<R> Add(R r) { return this.Add((left, right) -> r); } public final <R> PartialMatchBuilderNeg<R> Mult(MultMapper<Expression, R> Mult) { return new PartialMatchBuilderNeg<>(null, null, Mult); } public final <R> PartialMatchBuilderNeg<R> Mult(R r) { return this.Mult((left, right) -> r); } public final <R> PartialMatchBuilder<R> Neg(Function<Expression, R> Neg) { return new PartialMatchBuilder<>(null, null, null, Neg); } public final <R> PartialMatchBuilder<R> Neg(R r) { return this.Neg((expr) -> r); } } public static final class TotalMatchBuilderAdd<R> extends PartialMatchBuilder<R> { private TotalMatchBuilderAdd(Function<Integer, R> Const) { super(Const, null, null, null); } public final TotalMatchBuilderMult<R> Add(AddMapper<Expression, R> Add) { return new TotalMatchBuilderMult<>(super.Const, Add); } public final TotalMatchBuilderMult<R> Add(R r) { return this.Add((left, right) -> r); } public final PartialMatchBuilderNeg<R> Mult(MultMapper<Expression, R> Mult) { return new PartialMatchBuilderNeg<>(super.Const, null, Mult); } public final PartialMatchBuilderNeg<R> Mult(R r) { return this.Mult((left, right) -> r); } public final PartialMatchBuilder<R> Neg(Function<Expression, R> Neg) { return new PartialMatchBuilder<>(super.Const, null, null, Neg); } public final PartialMatchBuilder<R> Neg(R r) { return this.Neg((expr) -> r); } } public static final class TotalMatchBuilderMult<R> extends PartialMatchBuilder<R> { private TotalMatchBuilderMult(Function<Integer, R> Const, AddMapper<Expression, R> Add) { super(Const, Add, null, null); } public final TotalMatchBuilderNeg<R> Mult(MultMapper<Expression, R> Mult) { return new TotalMatchBuilderNeg<>(super.Const, super.Add, Mult); } public final TotalMatchBuilderNeg<R> Mult(R r) { return this.Mult((left, right) -> r); } public final PartialMatchBuilder<R> Neg(Function<Expression, R> Neg) { return new PartialMatchBuilder<>(super.Const, super.Add, null, Neg); } public final PartialMatchBuilder<R> Neg(R r) { return this.Neg((expr) -> r); } } public static final class TotalMatchBuilderNeg<R> extends PartialMatchBuilder<R> { private TotalMatchBuilderNeg(Function<Integer, R> Const, AddMapper<Expression, R> Add, MultMapper<Expression, R> Mult) { super(Const, Add, Mult, null); } public final Function<Expression, R> Neg(Function<Expression, R> Neg) { Expression.Cases<R> cases = Expressions.cases(super.Const, super.Add, super.Mult, Neg); return expression -> expression.match(cases); } public final Function<Expression, R> Neg(R r) { return this.Neg((expr) -> r); } } public static class PartialMatchBuilderAdd<R> extends PartialMatchBuilder<R> { private PartialMatchBuilderAdd(Function<Integer, R> Const) { super(Const, null, null, null); } public final PartialMatchBuilderMult<R> Add(AddMapper<Expression, R> Add) { return new PartialMatchBuilderMult<>(super.Const, Add); } public final PartialMatchBuilderMult<R> Add(R r) { return this.Add((left, right) -> r); } public final PartialMatchBuilderNeg<R> Mult(MultMapper<Expression, R> Mult) { return new PartialMatchBuilderNeg<>(super.Const, null, Mult); } public final PartialMatchBuilderNeg<R> Mult(R r) { return this.Mult((left, right) -> r); } public final PartialMatchBuilder<R> Neg(Function<Expression, R> Neg) { return new PartialMatchBuilder<>(super.Const, null, null, Neg); } public final PartialMatchBuilder<R> Neg(R r) { return this.Neg((expr) -> r); } } public static class PartialMatchBuilderMult<R> extends PartialMatchBuilder<R> { private PartialMatchBuilderMult(Function<Integer, R> Const, AddMapper<Expression, R> Add) { super(Const, Add, null, null); } public final PartialMatchBuilderNeg<R> Mult(MultMapper<Expression, R> Mult) { return new PartialMatchBuilderNeg<>(super.Const, super.Add, Mult); } public final PartialMatchBuilderNeg<R> Mult(R r) { return this.Mult((left, right) -> r); } public final PartialMatchBuilder<R> Neg(Function<Expression, R> Neg) { return new PartialMatchBuilder<>(super.Const, super.Add, null, Neg); } public final PartialMatchBuilder<R> Neg(R r) { return this.Neg((expr) -> r); } } public static class PartialMatchBuilderNeg<R> extends PartialMatchBuilder<R> { private PartialMatchBuilderNeg(Function<Integer, R> Const, AddMapper<Expression, R> Add, MultMapper<Expression, R> Mult) { super(Const, Add, Mult, null); } public final PartialMatchBuilder<R> Neg(Function<Expression, R> Neg) { return new PartialMatchBuilder<>(super.Const, super.Add, super.Mult, Neg); } public final PartialMatchBuilder<R> Neg(R r) { return this.Neg((expr) -> r); } } public static class PartialMatchBuilder<R> { private final Function<Integer, R> Const; private final AddMapper<Expression, R> Add; private final MultMapper<Expression, R> Mult; private final Function<Expression, R> Neg; private PartialMatchBuilder(Function<Integer, R> Const, AddMapper<Expression, R> Add, MultMapper<Expression, R> Mult, Function<Expression, R> Neg) { this.Const = Const; this.Add = Add; this.Mult = Mult; @@ -396,5 +460,21 @@ public final Function<Expression, R> otherwise(Supplier<R> otherwise) { this.Neg != null ? this.Neg : (expr) -> otherwise.get()); return expression -> expression.match(cases); } public final Function<Expression, R> otherwise(R r) { return this.otherwise(() -> r); } public final Function<Expression, Optional<R>> otherwiseEmpty() { Expression.Cases<Optional<R>> cases = Expressions.cases((this.Const != null) ? (value) -> Optional.of(this.Const.apply(value)) : (value) -> Optional.empty(), (this.Add != null) ? (left, right) -> Optional.of(this.Add.Add(left, right)) : (left, right) -> Optional.empty(), (this.Mult != null) ? (left, right) -> Optional.of(this.Mult.Mult(left, right)) : (left, right) -> Optional.empty(), (this.Neg != null) ? (expr) -> Optional.of(this.Neg.apply(expr)) : (expr) -> Optional.empty()); return expression -> expression.match(cases); } } } -
jbgi revised this gist
Oct 20, 2015 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ package org.derive4j.exemple; import java.lang.Integer; import java.lang.Object; -
jbgi revised this gist
Oct 20, 2015 . 1 changed file with 6 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ package test; import java.lang.Integer; import java.lang.Object; @@ -28,6 +28,8 @@ public final class Expressions { (left, right) -> Optional.empty(), (expr) -> Optional.of(expr)); private static final TotalMatchBuilderConst totalMatchBuilderConst = new TotalMatchBuilderConst(); private Expressions() { } @@ -119,8 +121,8 @@ public static Function<Expression, Expression> modExpr(Function<Expression, Expr return expression -> expression.match(cases); } public static TotalMatchBuilderConst cases() { return totalMatchBuilderConst; } private static final class Const extends Expression { @@ -395,4 +397,4 @@ public final Function<Expression, R> otherwise(Supplier<R> otherwise) { return expression -> expression.match(cases); } } } -
jbgi renamed this gist
Oct 19, 2015 . 1 changed file with 1 addition and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,3 @@ package org.derive4j.exemple; import java.lang.Integer; @@ -396,5 +395,4 @@ public final Function<Expression, R> otherwise(Supplier<R> otherwise) { return expression -> expression.match(cases); } } } -
jbgi revised this gist
Oct 19, 2015 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,4 @@ ```java package org.derive4j.exemple; import java.lang.Integer; @@ -396,3 +397,4 @@ public final class Expressions { } } } ``` -
jbgi created this gist
Oct 19, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,398 @@ package org.derive4j.exemple; import java.lang.Integer; import java.lang.Object; import java.lang.Override; import java.util.Optional; import java.util.function.Function; import java.util.function.Supplier; public final class Expressions { private static final Expression.Cases<Optional<Integer>> valueGetter = Expressions.cases((value) -> Optional.of(value), (left, right) -> Optional.empty(), (left, right) -> Optional.empty(), (expr) -> Optional.empty()); private static final Expression.Cases<Optional<Expression>> leftGetter = Expressions.cases((value) -> Optional.empty(), (left, right) -> Optional.of(left), (left, right) -> Optional.of(left), (expr) -> Optional.empty()); private static final Expression.Cases<Optional<Expression>> rightGetter = Expressions.cases((value) -> Optional.empty(), (left, right) -> Optional.of(right), (left, right) -> Optional.of(right), (expr) -> Optional.empty()); private static final Expression.Cases<Optional<Expression>> exprGetter = Expressions.cases((value) -> Optional.empty(), (left, right) -> Optional.empty(), (left, right) -> Optional.empty(), (expr) -> Optional.of(expr)); private Expressions() { } public static Expression Const(Integer value) { return new Const(value); } public static Expression Add(Expression left, Expression right) { return new Add(left, right); } public static Expression Mult(Expression left, Expression right) { return new Mult(left, right); } public static Expression Neg(Expression expr) { return new Neg(expr); } public static Expression lazy(Supplier<Expression> expression) { return new Lazy(expression); } public static <R> Expression.Cases<R> cases(ConstMapper<R> Const, AddMapper<R> Add, MultMapper<R> Mult, NegMapper<R> Neg) { return new LambdaCases<>(Const, Add, Mult, Neg); } public static Optional<Integer> getValue(Expression expression) { return expression.match(valueGetter); } public static Optional<Expression> getLeft(Expression expression) { return expression.match(leftGetter); } public static Optional<Expression> getRight(Expression expression) { return expression.match(rightGetter); } public static Optional<Expression> getExpr(Expression expression) { return expression.match(exprGetter); } public static Function<Expression, Expression> setValue(Integer newValue) { return modValue(__ -> newValue); } public static Function<Expression, Expression> modValue(Function<Integer, Integer> valueMod) { Expression.Cases<Expression> cases = Expressions.cases((value) -> Const(valueMod.apply(value)), (left, right) -> Add(left, right), (left, right) -> Mult(left, right), (expr) -> Neg(expr)); return expression -> expression.match(cases); } public static Function<Expression, Expression> setLeft(Expression newLeft) { return modLeft(__ -> newLeft); } public static Function<Expression, Expression> modLeft(Function<Expression, Expression> leftMod) { Expression.Cases<Expression> cases = Expressions.cases((value) -> Const(value), (left, right) -> Add(leftMod.apply(left), right), (left, right) -> Mult(leftMod.apply(left), right), (expr) -> Neg(expr)); return expression -> expression.match(cases); } public static Function<Expression, Expression> setRight(Expression newRight) { return modRight(__ -> newRight); } public static Function<Expression, Expression> modRight(Function<Expression, Expression> rightMod) { Expression.Cases<Expression> cases = Expressions.cases((value) -> Const(value), (left, right) -> Add(left, rightMod.apply(right)), (left, right) -> Mult(left, rightMod.apply(right)), (expr) -> Neg(expr)); return expression -> expression.match(cases); } public static Function<Expression, Expression> setExpr(Expression newExpr) { return modExpr(__ -> newExpr); } public static Function<Expression, Expression> modExpr(Function<Expression, Expression> exprMod) { Expression.Cases<Expression> cases = Expressions.cases((value) -> Const(value), (left, right) -> Add(left, right), (left, right) -> Mult(left, right), (expr) -> Neg(exprMod.apply(expr))); return expression -> expression.match(cases); } public static TotalMatchBuilderConst match() { return new TotalMatchBuilderConst(); } private static final class Const extends Expression { private final Integer value; Const(Integer value) { this.value = value; } @Override public <R> R match(Expression.Cases<R> cases) { return cases.Const(this.value); } } private static final class Add extends Expression { private final Expression left; private final Expression right; Add(Expression left, Expression right) { this.left = left; this.right = right; } @Override public <R> R match(Expression.Cases<R> cases) { return cases.Add(this.left, this.right); } } private static final class Mult extends Expression { private final Expression left; private final Expression right; Mult(Expression left, Expression right) { this.left = left; this.right = right; } @Override public <R> R match(Expression.Cases<R> cases) { return cases.Mult(this.left, this.right); } } private static final class Neg extends Expression { private final Expression expr; Neg(Expression expr) { this.expr = expr; } @Override public <R> R match(Expression.Cases<R> cases) { return cases.Neg(this.expr); } } private static final class Lazy extends Expression { private final Object lock = new Object(); private Supplier<Expression> expression; private volatile Expression evaluation; Lazy(Supplier<Expression> expression) { this.expression = expression; } private Expression eval() { Expression _evaluation = this.evaluation; if (_evaluation == null) { synchronized (this.lock) { _evaluation = this.evaluation; if (_evaluation == null) { this.evaluation = _evaluation = expression.get(); this.expression = null; } } } return _evaluation; } @Override public <R> R match(Expression.Cases<R> cases) { return this.eval().match(cases); } } public interface ConstMapper<R> { R Const(Integer value); } public interface AddMapper<R> { R Add(Expression left, Expression right); } public interface MultMapper<R> { R Mult(Expression left, Expression right); } public interface NegMapper<R> { R Neg(Expression expr); } private static final class LambdaCases<R> implements Expression.Cases<R> { private final ConstMapper<R> Const; private final AddMapper<R> Add; private final MultMapper<R> Mult; private final NegMapper<R> Neg; LambdaCases(ConstMapper<R> Const, AddMapper<R> Add, MultMapper<R> Mult, NegMapper<R> Neg) { this.Const = Const; this.Add = Add; this.Mult = Mult; this.Neg = Neg; } @Override public R Const(Integer value) { return this.Const.Const(value); } @Override public R Add(Expression left, Expression right) { return this.Add.Add(left, right); } @Override public R Mult(Expression left, Expression right) { return this.Mult.Mult(left, right); } @Override public R Neg(Expression expr) { return this.Neg.Neg(expr); } } public static final class TotalMatchBuilderConst { private TotalMatchBuilderConst() { } public final <R> TotalMatchBuilderAdd<R> Const(ConstMapper<R> Const) { return new TotalMatchBuilderAdd<>(Const); } public final <R> PartialMatchBuilderMult<R> Add(AddMapper<R> Add) { return new PartialMatchBuilderMult<>(null, Add); } public final <R> PartialMatchBuilderNeg<R> Mult(MultMapper<R> Mult) { return new PartialMatchBuilderNeg<>(null, null, Mult); } public final <R> PartialMatchBuilder<R> Neg(NegMapper<R> Neg) { return new PartialMatchBuilder<>(null, null, null, Neg); } } public static final class TotalMatchBuilderAdd<R> extends PartialMatchBuilder<R> { private TotalMatchBuilderAdd(ConstMapper<R> Const) { super(Const, null, null, null); } public final TotalMatchBuilderMult<R> Add(AddMapper<R> Add) { return new TotalMatchBuilderMult<>(super.Const, Add); } public final PartialMatchBuilderNeg<R> Mult(MultMapper<R> Mult) { return new PartialMatchBuilderNeg<>(super.Const, null, Mult); } public final PartialMatchBuilder<R> Neg(NegMapper<R> Neg) { return new PartialMatchBuilder<>(super.Const, null, null, Neg); } } public static final class TotalMatchBuilderMult<R> extends PartialMatchBuilder<R> { private TotalMatchBuilderMult(ConstMapper<R> Const, AddMapper<R> Add) { super(Const, Add, null, null); } public final TotalMatchBuilderNeg<R> Mult(MultMapper<R> Mult) { return new TotalMatchBuilderNeg<>(super.Const, super.Add, Mult); } public final PartialMatchBuilder<R> Neg(NegMapper<R> Neg) { return new PartialMatchBuilder<>(super.Const, super.Add, null, Neg); } } public static final class TotalMatchBuilderNeg<R> extends PartialMatchBuilder<R> { private TotalMatchBuilderNeg(ConstMapper<R> Const, AddMapper<R> Add, MultMapper<R> Mult) { super(Const, Add, Mult, null); } public final Function<Expression, R> Neg(NegMapper<R> Neg) { Expression.Cases<R> cases = Expressions.cases(super.Const, super.Add, super.Mult, Neg); return expression -> expression.match(cases); } } public static class PartialMatchBuilderAdd<R> extends PartialMatchBuilder<R> { private PartialMatchBuilderAdd(ConstMapper<R> Const) { super(Const, null, null, null); } public final PartialMatchBuilderMult<R> Add(AddMapper<R> Add) { return new PartialMatchBuilderMult<>(super.Const, Add); } public final PartialMatchBuilderNeg<R> Mult(MultMapper<R> Mult) { return new PartialMatchBuilderNeg<>(super.Const, null, Mult); } public final PartialMatchBuilder<R> Neg(NegMapper<R> Neg) { return new PartialMatchBuilder<>(super.Const, null, null, Neg); } } public static class PartialMatchBuilderMult<R> extends PartialMatchBuilder<R> { private PartialMatchBuilderMult(ConstMapper<R> Const, AddMapper<R> Add) { super(Const, Add, null, null); } public final PartialMatchBuilderNeg<R> Mult(MultMapper<R> Mult) { return new PartialMatchBuilderNeg<>(super.Const, super.Add, Mult); } public final PartialMatchBuilder<R> Neg(NegMapper<R> Neg) { return new PartialMatchBuilder<>(super.Const, super.Add, null, Neg); } } public static class PartialMatchBuilderNeg<R> extends PartialMatchBuilder<R> { private PartialMatchBuilderNeg(ConstMapper<R> Const, AddMapper<R> Add, MultMapper<R> Mult) { super(Const, Add, Mult, null); } public final PartialMatchBuilder<R> Neg(NegMapper<R> Neg) { return new PartialMatchBuilder<>(super.Const, super.Add, super.Mult, Neg); } } public static class PartialMatchBuilder<R> { private final ConstMapper<R> Const; private final AddMapper<R> Add; private final MultMapper<R> Mult; private final NegMapper<R> Neg; private PartialMatchBuilder(ConstMapper<R> Const, AddMapper<R> Add, MultMapper<R> Mult, NegMapper<R> Neg) { this.Const = Const; this.Add = Add; this.Mult = Mult; this.Neg = Neg; } public final Function<Expression, R> otherwise(Supplier<R> otherwise) { Expression.Cases<R> cases = Expressions.cases(this.Const != null ? this.Const : (value) -> otherwise.get(), this.Add != null ? this.Add : (left, right) -> otherwise.get(), this.Mult != null ? this.Mult : (left, right) -> otherwise.get(), this.Neg != null ? this.Neg : (expr) -> otherwise.get()); return expression -> expression.match(cases); } } }