Creata astrazione della struttura if...then...else...

This commit is contained in:
Fabio Scotto di Santolo
2020-01-23 17:54:18 +01:00
committed by Fabio Scotto di Santolo
parent 39f49cd0d3
commit 46cdb250e3
8 changed files with 142 additions and 2 deletions

View File

@@ -1,11 +1,13 @@
package org.gym.fp.fpjava;
import org.gym.fp.fpjava.demo.AbstractControlStructureDemo;
import org.gym.fp.fpjava.demo.FunctionDemo;
public class Main {
public static void main(String[] args) {
FunctionDemo.run();
AbstractControlStructureDemo.run();
}
}

View File

@@ -0,0 +1,49 @@
package org.gym.fp.fpjava.demo;
import org.gym.fp.fpjava.type.Effect;
import org.gym.fp.fpjava.type.Function;
import org.gym.fp.fpjava.type.Result;
import java.util.regex.Pattern;
import static org.gym.fp.fpjava.type.Case.match;
import static org.gym.fp.fpjava.type.Case.when;
public class AbstractControlStructureDemo {
public static void run() {
doEmailValidationDemo();
}
private static void doEmailValidationDemo() {
validate("this.is@my.email");
validate(null);
validate("");
validate("john.doe@acme.com");
}
private static void validate(String email) {
final EmailValidation validation = new EmailValidation();
final Function<String, Result<String>> emailChecker = validation.emailChecker;
final Effect<String> success = validation.success;
final Effect<String> failure = validation.failure;
emailChecker.apply(email).bind(success, failure);
}
}
class EmailValidation {
public final Pattern emailPattern =
Pattern.compile("^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$");
public final Effect<String> success =
email -> System.out.println("Verification mail sent to " + email);
public final Effect<String> failure =
msg -> System.err.println("Error message logged: " + msg);
public final Function<String, Result<String>> emailChecker = s -> match(
when(() -> Result.success(s)),
when(() -> s == null, () -> Result.failure("email must not be null")),
when(() -> s.length() == 0, () -> Result.failure("email must not be empty")),
when(() -> !emailPattern.matcher(s).matches(), () -> Result.failure("email " + s + " is invalid")));
}

View File

@@ -0,0 +1,31 @@
package org.gym.fp.fpjava.type;
public class Case<T> extends Tuple<Supplier<Boolean>, Supplier<Result<T>>> {
public Case(Supplier<Boolean> booleanSupplier, Supplier<Result<T>> resultSupplier) {
super(booleanSupplier, resultSupplier);
}
private static class DefaultCase<T> extends Case<T> {
public DefaultCase(Supplier<Boolean> booleanSupplier, Supplier<Result<T>> resultSupplier) {
super(booleanSupplier, resultSupplier);
}
}
public static <T> Case<T> when(Supplier<Boolean> condition, Supplier<Result<T>> value) {
return new Case<>(condition, value);
}
public static <T> DefaultCase<T> when(Supplier<Result<T>> value) {
return new DefaultCase<>(() -> true, value);
}
@SafeVarargs
public static <T> Result<T> match(DefaultCase<T> defaultCase, Case<T>... matchers) {
for (Case<T> aCase : matchers) {
if (aCase._1.get()) return aCase._2.get();
}
return defaultCase._2.get();
}
}

View File

@@ -0,0 +1,5 @@
package org.gym.fp.fpjava.type;
public interface Effect<T> {
void apply(T t);
}

View File

@@ -0,0 +1,5 @@
package org.gym.fp.fpjava.type;
public interface Executable {
void exec();
}

View File

@@ -0,0 +1,43 @@
package org.gym.fp.fpjava.type;
public interface Result<T> {
void bind(Effect<T> success, Effect<T> failure);
static <T> Result<T> failure(String message) {
return new Failure<>(message);
}
static <T> Result<T> success(T value) {
return new Success<>(value);
}
class Success<T> implements Result<T> {
private final T value;
public Success(T value) {
this.value = value;
}
@Override
public void bind(Effect<T> success, Effect<T> failure) {
success.apply(value);
}
}
class Failure<T> implements Result<T> {
private final String errorMessage;
public Failure(String msg) {
this.errorMessage = msg;
}
public String getMessage() {
return this.errorMessage;
}
@Override
public void bind(Effect success, Effect failure) {
failure.apply(errorMessage);
}
}
}

View File

@@ -0,0 +1,5 @@
package org.gym.fp.fpjava.type;
public interface Supplier<T> {
T get();
}

View File

@@ -1,8 +1,8 @@
package org.gym.fp.fpjava.type;
public class Tuple<A, B> {
private final A _1;
private final B _2;
public final A _1;
public final B _2;
public Tuple(A first, B second) {
this._1 = first;