Skip to content

Instantly share code, notes, and snippets.

@calam1
Last active June 7, 2018 13:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save calam1/6f011d434def52a33af2 to your computer and use it in GitHub Desktop.
Save calam1/6f011d434def52a33af2 to your computer and use it in GitHub Desktop.
Example of idea(How We Used category theory to solve a problem in java) presented in http://techblog.realestate.com.au/how-we-used-category-theory-to-solve-a-problem-in-java/?utm_medium=email&utm_source=flipboard
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
public class ExtensionTester {
//================================ Supporting classes ======================================
interface Request {
String getDecider();
String getCity();
Map<String, String> getFakeHttpRequest();
}
static class RequestImpl implements Request{
private String decider;
private String city;
private Map<String, String> fakeHttpRequest;
public RequestImpl(String decider, String city) {
this.decider = decider;
this.city = city;
this.fakeHttpRequest = new HashMap<>();
}
@Override
public String getDecider() {
return decider;
}
@Override
public String getCity() {
return city;
}
@Override
public Map<String, String> getFakeHttpRequest() {
return fakeHttpRequest;
}
}
static class RequestDifferent implements Request{
private String decider;
private String city;
private String color;
private Map<String, String> fakeHttpRequest;
RequestDifferent(String decider, String city) {
this.decider = decider;
this.city = city;
}
@Override
public String getDecider() {
return decider;
}
@Override
public String getCity() {
return city;
}
@Override
public Map<String, String> getFakeHttpRequest() {
return fakeHttpRequest;
}
public void setFakeHttpRequest(Map<String, String> fakeHttpRequest) {
this.fakeHttpRequest = fakeHttpRequest;
}
public void setColor(String color) {
this.color = color;
}
public String getColor() {
return color;
}
}
interface Response {
String getData();
void setData(String s);
boolean isCityClose();
void setIsCityClose(boolean b);
String getColor();
void setColor(String color);
}
static class ResponseImpl implements Response {
private String data;
private boolean isCityClose;
private String color;
public ResponseImpl(String data, boolean isClose) {
this.data = data;
this.isCityClose = isClose;
}
@Override
public String getData() {
return data;
}
@Override
public void setData(String s) {
this.data = s;
}
@Override
public boolean isCityClose() {
return isCityClose;
}
@Override
public void setIsCityClose(boolean isClose) {
this.isCityClose = isClose;
}
@Override
public String getColor() {
return color;
}
@Override
public void setColor(String color) {
this.color = color;
}
}
static class DifferentResponseImpl implements Response {
private String data;
private boolean isClose;
private String color;
private String shape;
public DifferentResponseImpl(String data, boolean isClose) {
this.data = data;
this.isClose = isClose;
}
@Override
public String getData() {
return data;
}
@Override
public void setData(String s) {
this.data = s;
}
@Override
public boolean isCityClose() {
return isClose;
}
@Override
public void setIsCityClose(boolean isClose) {
this.isClose = isClose;
}
@Override
public String getColor() {
return color;
}
@Override
public void setColor(String color) {
this.color = color;
}
public String getShape() {
return shape;
}
public void setShape(String shape) {
this.shape = shape;
}
}
//================================ Extension classes ======================================
interface Extension<S> {
Response apply(S source, Response response);
default Extension<S> compose(Extension<S> extension) {
return (source, response) -> extension.apply(source, Extension.this.apply(source, response));
}
static final Extension IDENTITY = (s, r) -> r;
static <S> Extension<S> composeAll(Extension<S>... extensions) {
return Stream.of(extensions).reduce(IDENTITY, Extension::compose);
}
default <T> Extension<T> contraMap(Function<T, S> function) {
return (T source, Response response) -> Extension.this.apply(function.apply(source), response);
}
}
static class ExtensionImpl implements Extension<Request> {
@Override
public Response apply(Request source, Response response) {
System.out.println("In Extension 1");
if (source.getDecider().equals("chris")) {
String data = response.getData();
data += " extension 1 ";
response.setData(data);
}
return response;
}
}
static class ExtensionImpl2 implements Extension<Request> {
@Override
public Response apply(Request source, Response response) {
System.out.println("In Extension 2");
if (source.getCity().equals("chicago")) {
response.setIsCityClose(true);
} else {
response.setIsCityClose(false);
}
return response;
}
}
static class ExtensionImpl3 implements Extension<RequestDifferent> {
@Override
public Response apply(RequestDifferent source, Response response) {
System.out.println("In Extension 3");
response.setColor(source.getColor());
return response;
}
}
public static void main(String[] args) {
//Set up the request and response - this mimics what comes out of the original RESTful call
Request request = new RequestImpl("chris", "chicago");
request.getFakeHttpRequest().put("color", "red");
Response response = new ResponseImpl("Original_response", false);
System.out.println("original response color: " + response.getColor());
System.out.println("original response data: " + response.getData());
System.out.println("original response isclose: " + response.isCityClose());
//Customizations - i.e. Extensions
Extension<Request> extension = new ExtensionImpl();
Extension<Request> extension2 = new ExtensionImpl2();
Extension<RequestDifferent> extension3 = new ExtensionImpl3();
//Function to contra-vert the child
// Function<Request, RequestDifferent> convert = r -> (RequestDifferent) r;
Function<Request, RequestDifferent> convert = r -> {
String color = r.getFakeHttpRequest().get("color");
RequestDifferent rd = new RequestDifferent(r.getDecider(), r.getCity());
rd.setFakeHttpRequest(r.getFakeHttpRequest());
rd.setColor(color);
return rd;
};
List<Extension<Request>> extensionList = new ArrayList<Extension<Request>>() {{
add(extension);
add(extension2);
add(extension3.contraMap(convert));
}};
Extension<Request> [] extensions = extensionList.toArray(new Extension[extensionList.size()]);
//compose all the extensions
Response result = Extension.composeAll(extensions).apply(request, response);
//check data to see if it is changed
System.out.println(result.getData());
System.out.println("Is city close: " + result.isCityClose());
System.out.println("The color is: " + result.getColor());
System.out.println("The data is: " + result.getData());
}
}
@vertexcite
Copy link

vertexcite commented Aug 18, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment