Last active
June 7, 2018 13:24
-
-
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
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 characters
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()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
this.isCityClose = isClose
needed after https://gist.github.com/calam1/6f011d434def52a33af2#file-extensiontester-java-L97 ?(Edited:
And also after https://gist.github.com/calam1/6f011d434def52a33af2#file-extensiontester-java-L138 )