add lab6
This commit is contained in:
18
Lab6/cs2030s/fp/Action.java
Normal file
18
Lab6/cs2030s/fp/Action.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package cs2030s.fp;
|
||||
|
||||
/**
|
||||
* Represent a function that acts on a value.
|
||||
* CS2030S Lab 5
|
||||
* AY22/23 Semester 1
|
||||
*
|
||||
* @param <T> The type of the input value.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface Action<T> {
|
||||
/**
|
||||
* The functional method to act on the value t.
|
||||
*
|
||||
* @param t The input value.
|
||||
*/
|
||||
void call(T t);
|
||||
}
|
||||
17
Lab6/cs2030s/fp/Actionable.java
Normal file
17
Lab6/cs2030s/fp/Actionable.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package cs2030s.fp;
|
||||
|
||||
/**
|
||||
* Represent a container that can act on its content.
|
||||
* CS2030S Lab 5
|
||||
* AY22/23 Semester 1
|
||||
*
|
||||
* @param <T> The type of the content.
|
||||
*/
|
||||
interface Actionable<T> {
|
||||
/**
|
||||
* The method to act on its content.
|
||||
*
|
||||
* @param f The action.
|
||||
*/
|
||||
void act(Action<? super T> f);
|
||||
}
|
||||
176
Lab6/cs2030s/fp/Actually.java
Normal file
176
Lab6/cs2030s/fp/Actually.java
Normal file
@@ -0,0 +1,176 @@
|
||||
package cs2030s.fp;
|
||||
|
||||
public abstract class Actually<T> implements Immutatorable<T>, Actionable<T> {
|
||||
|
||||
public static <T> Actually<T> ok(T value) {
|
||||
return new Success<T>(value);
|
||||
}
|
||||
|
||||
public static <T> Actually<T> err(Exception e) {
|
||||
// It is okay to do an unchecked cast here as failure types don't use
|
||||
// the value T.
|
||||
@SuppressWarnings("unchecked")
|
||||
Actually<T> failure = (Actually<T>) new Failure(e);
|
||||
return failure;
|
||||
}
|
||||
|
||||
public abstract T unwrap() throws Exception;
|
||||
|
||||
public abstract T except(Constant<? extends T> c);
|
||||
|
||||
public abstract void finish(Action<? super T> action);
|
||||
|
||||
public abstract <U extends T> T unless(U other);
|
||||
|
||||
public abstract <R> Actually<R> next(Immutator<? extends Actually<? extends R>, ? super T> immutator);
|
||||
|
||||
private static class Success<T> extends Actually<T> {
|
||||
private final T value;
|
||||
|
||||
private Success(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T unwrap() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T except(Constant<? extends T> c) {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish(Action<? super T> action) {
|
||||
action.call(this.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U extends T> T unless(U other) {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> Actually<R> next(Immutator<? extends Actually<? extends R>, ? super T> immutator) {
|
||||
try {
|
||||
// it is okay to cast from <? extends R> to <R>
|
||||
@SuppressWarnings("unchecked")
|
||||
Actually<R> result = (Actually<R>) immutator.invoke(this.value);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return Actually.err(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> Actually<R> transform(Immutator<? extends R, ? super T> immutator) {
|
||||
try {
|
||||
return Actually.ok(immutator.invoke(this.value));
|
||||
} catch (Exception e) {
|
||||
return Actually.err(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(Action<? super T> action) {
|
||||
action.call(this.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<" + value + ">";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof Success<?>) {
|
||||
Success<?> other = (Success<?>) obj;
|
||||
if (this.value == other.value) {
|
||||
return true;
|
||||
}
|
||||
if (this.value != null && this.value.equals(other.value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class Failure extends Actually<Object> {
|
||||
private final Exception e;
|
||||
|
||||
Failure(Exception e) {
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object unwrap() throws Exception {
|
||||
throw e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object except(Constant<? extends Object> c) {
|
||||
return c.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object unless(Object other) {
|
||||
return other;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish(Action<? super Object> action) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> Actually<R> transform(Immutator<? extends R, ? super Object> immutator) {
|
||||
return Actually.err(this.e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> Actually<R> next(Immutator<? extends Actually<? extends R>, ? super Object> immutator) {
|
||||
return Actually.err(this.e);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(Action<? super Object> action) {
|
||||
// Do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + e.getClass().getName() + "] " + e.getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof Failure) {
|
||||
Failure other = (Failure) obj;
|
||||
if (this.e == other.e) {
|
||||
return true;
|
||||
}
|
||||
if (this.e == null || other.e == null) {
|
||||
return false;
|
||||
}
|
||||
if (this.e.getMessage() == null || other.e.getMessage() == null) {
|
||||
return false;
|
||||
}
|
||||
return this.e.getMessage() == other.e.getMessage();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
23
Lab6/cs2030s/fp/Combiner.java
Normal file
23
Lab6/cs2030s/fp/Combiner.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package cs2030s.fp;
|
||||
|
||||
/**
|
||||
* Represent a function that combines two values into one. The two inputs
|
||||
* and the result can be of different types.
|
||||
* CS2030S Lab 5
|
||||
* AY20/21 Semester 2
|
||||
*
|
||||
* @param <R> The type of the return value
|
||||
* @param <S> The type of the first input value
|
||||
* @param <T> The type of the second input value
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Combiner<R, S, T> {
|
||||
/**
|
||||
* The functional method to combines two values into one.
|
||||
*
|
||||
* @param s The first input value
|
||||
* @param t The second input value
|
||||
* @return The value after combining s and t.
|
||||
*/
|
||||
R combine(S s, T t);
|
||||
}
|
||||
18
Lab6/cs2030s/fp/Constant.java
Normal file
18
Lab6/cs2030s/fp/Constant.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package cs2030s.fp;
|
||||
|
||||
/**
|
||||
* Represent a function to initialise a constant value.
|
||||
* CS2030S Lab 5
|
||||
* AY22/23 Semester 1
|
||||
*
|
||||
* @param <T> The type of the constant value.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Constant<T> {
|
||||
/**
|
||||
* The functional method to initialise the constant.
|
||||
*
|
||||
* @return The constant value.
|
||||
*/
|
||||
T init();
|
||||
}
|
||||
20
Lab6/cs2030s/fp/Immutator.java
Normal file
20
Lab6/cs2030s/fp/Immutator.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package cs2030s.fp;
|
||||
|
||||
/**
|
||||
* Represent a function that immutate one value into another, possible of different types.
|
||||
* CS2030S Lab 5
|
||||
* AY22/23 Semester 1
|
||||
*
|
||||
* @param <R> The type of the result value.
|
||||
* @param <P> The type of the input value.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Immutator<R, P> {
|
||||
/**
|
||||
* The functional method to immutate the value p.
|
||||
*
|
||||
* @param p The input value.
|
||||
* @return The value after applying the given immutation on p.
|
||||
*/
|
||||
R invoke(P p);
|
||||
}
|
||||
18
Lab6/cs2030s/fp/Immutatorable.java
Normal file
18
Lab6/cs2030s/fp/Immutatorable.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package cs2030s.fp;
|
||||
|
||||
/**
|
||||
* Represent a container that can transforms its content to produce another container containing the immutated element, possible of different types.
|
||||
* CS2030S Lab 5
|
||||
* AY22/23 Semester 1
|
||||
*
|
||||
* @param <T> The type of the content.
|
||||
*/
|
||||
public interface Immutatorable<T> {
|
||||
/**
|
||||
* The method to produce another container with immutated element.
|
||||
*
|
||||
* @param f The immutator.
|
||||
* @return A new container containing the immutated element.
|
||||
*/
|
||||
<R> Immutatorable<R> transform(Immutator<? extends R, ? super T> f);
|
||||
}
|
||||
5
Lab6/cs2030s/fp/Lazy.java
Normal file
5
Lab6/cs2030s/fp/Lazy.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package cs2030s.fp;
|
||||
|
||||
public class Lazy<T> /* implements Immutatorable<T> */ {
|
||||
private Constant<? extends T> init;
|
||||
}
|
||||
5
Lab6/cs2030s/fp/Memo.java
Normal file
5
Lab6/cs2030s/fp/Memo.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package cs2030s.fp;
|
||||
|
||||
public class Memo<T> extends Lazy<T> {
|
||||
private Actually<T> value;
|
||||
}
|
||||
Reference in New Issue
Block a user