lab8 current progress
This commit is contained in:
18
Lab8/cs2030s/fp/Action.java
Normal file
18
Lab8/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
Lab8/cs2030s/fp/Actionable.java
Normal file
17
Lab8/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);
|
||||
}
|
||||
89
Lab8/cs2030s/fp/Actually.java
Normal file
89
Lab8/cs2030s/fp/Actually.java
Normal file
@@ -0,0 +1,89 @@
|
||||
package cs2030s.fp;
|
||||
|
||||
/**
|
||||
* A container class the encapsulate
|
||||
* a value that may or may not be an error.
|
||||
*
|
||||
* @author Adi Yoga S. Prabawa
|
||||
* @version CS2030S AY 22/23 Sem 1
|
||||
*/
|
||||
public class Actually<T> implements Immutatorable<T> {
|
||||
private T val;
|
||||
private Exception err;
|
||||
|
||||
private Actually(T val, Exception err) {
|
||||
this.val = val;
|
||||
this.err = err;
|
||||
}
|
||||
|
||||
public static <T> Actually<T> err() {
|
||||
// A common error for ease of use
|
||||
return new Actually<T>((T) null, new Exception("err"));
|
||||
}
|
||||
public static <T> Actually<T> err(Exception err) {
|
||||
return new Actually<T>((T) null, err);
|
||||
}
|
||||
public static <T> Actually<T> ok(T val) {
|
||||
return new Actually<T>(val, null);
|
||||
}
|
||||
|
||||
public T except(Constant<? extends T> com) {
|
||||
return this.err == null ? this.val : com.init();
|
||||
}
|
||||
public <U extends T> T unless(U val) {
|
||||
return this.err == null ? this.val : val;
|
||||
}
|
||||
public void finish(Action<? super T> act) {
|
||||
if (this.err == null) {
|
||||
act.call(this.val);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public <R> Actually<R> transform(Immutator<? extends R, ? super T> f) {
|
||||
return this.err == null ? Actually.<R>ok(f.invoke(this.val)) : Actually.<R>err(this.err);
|
||||
}
|
||||
public <R> Actually<? extends R> next(Immutator<? extends Actually<? extends R>, ? super T> f) {
|
||||
if (this.err != null) {
|
||||
return Actually.err(this.err);
|
||||
} else {
|
||||
return f.invoke(this.val);
|
||||
}
|
||||
}
|
||||
public Actually<T> check(Immutator<Boolean, ? super T> pred) {
|
||||
if (this.err != null) {
|
||||
return Actually.err(this.err);
|
||||
}
|
||||
Boolean chk = pred.invoke(this.val);
|
||||
if (chk) {
|
||||
return this;
|
||||
}
|
||||
return Actually.err();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (this.err != null) {
|
||||
return "<>";
|
||||
}
|
||||
return "<" + this.val + ">";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof Actually<?>)) {
|
||||
return false;
|
||||
}
|
||||
Actually<?> that = (Actually<?>) obj;
|
||||
if (this.err != null) {
|
||||
// for simplicity, all err is the same
|
||||
return that.err != null;
|
||||
}
|
||||
if (this.val == null) {
|
||||
return that.val == null;
|
||||
}
|
||||
return this.val.equals(that.val);
|
||||
}
|
||||
}
|
||||
23
Lab8/cs2030s/fp/Combiner.java
Normal file
23
Lab8/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
Lab8/cs2030s/fp/Constant.java
Normal file
18
Lab8/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
Lab8/cs2030s/fp/Immutator.java
Normal file
20
Lab8/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
Lab8/cs2030s/fp/Immutatorable.java
Normal file
18
Lab8/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);
|
||||
}
|
||||
145
Lab8/cs2030s/fp/InfiniteList.java
Normal file
145
Lab8/cs2030s/fp/InfiniteList.java
Normal file
@@ -0,0 +1,145 @@
|
||||
package cs2030s.fp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class InfiniteList<T> {
|
||||
private Memo<Actually<T>> head;
|
||||
private Memo<InfiniteList<T>> tail;
|
||||
|
||||
public static final End END = new End();
|
||||
|
||||
public static <T> InfiniteList<T> end() {
|
||||
@SuppressWarnings("unchecked")
|
||||
InfiniteList<T> result = (InfiniteList<T>) END;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static class End extends InfiniteList<Object> {
|
||||
private End() {
|
||||
super(null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object head() {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfiniteList<Object> tail() {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnd() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "-";
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfiniteList<Object> limit(long n) {
|
||||
return InfiniteList.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfiniteList<Object> filter(Immutator<Boolean, ? super Object> pred) {
|
||||
return InfiniteList.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> InfiniteList<R> map(Immutator<? extends R, ? super Object> f) {
|
||||
return InfiniteList.end();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private InfiniteList(Memo<Actually<T>> head, Memo<InfiniteList<T>> tail) {
|
||||
this.head = head;
|
||||
this.tail = tail;
|
||||
}
|
||||
|
||||
// You may add other private constructor but it's not necessary.
|
||||
|
||||
public static <T> InfiniteList<T> generate(Constant<T> prod) {
|
||||
Memo<Actually<T>> head = Memo.from(() -> Actually.ok(prod.init()));
|
||||
Memo<InfiniteList<T>> tail = Memo.from(() -> generate(prod));
|
||||
return new InfiniteList<>(head, tail);
|
||||
}
|
||||
|
||||
public static <T> InfiniteList<T> iterate(T seed, Immutator<T, T> func) {
|
||||
Memo<Actually<T>> head = Memo.from(() -> Actually.ok(seed));
|
||||
Memo<InfiniteList<T>> tail = Memo.from(() -> iterate(func.invoke(seed), func));
|
||||
return new InfiniteList<>(head, tail);
|
||||
}
|
||||
|
||||
public T head() {
|
||||
return this.head.get().except(() -> this.tail.get().head());
|
||||
}
|
||||
|
||||
public InfiniteList<T> tail() {
|
||||
return this.head.get().transform(h -> this.tail.get()).except(() -> this.tail.get().tail());
|
||||
}
|
||||
|
||||
public <R> InfiniteList<R> map(Immutator<? extends R, ? super T> f) {
|
||||
Memo<Actually<R>> head = Memo.from(() -> this.head.get().transform(f));
|
||||
Memo<InfiniteList<R>> tail = Memo.from(() -> this.tail.get().map(f));
|
||||
return new InfiniteList<R>(head, tail);
|
||||
}
|
||||
|
||||
public InfiniteList<T> filter(Immutator<Boolean, ? super T> pred) {
|
||||
Memo<Actually<T>> head = Memo.from(() -> this.head.get().check(pred));
|
||||
Memo<InfiniteList<T>> tail = Memo.from(() -> this.tail.get().filter(pred));
|
||||
return new InfiniteList<>(head, tail);
|
||||
}
|
||||
|
||||
public InfiniteList<T> limit(long n) {
|
||||
if (n <= 0) {
|
||||
return InfiniteList.end();
|
||||
}
|
||||
if (this.isEnd()) {
|
||||
return InfiniteList.end();
|
||||
}
|
||||
|
||||
Memo<Actually<T>> head = Memo.from(() -> Actually.ok(this.head()));
|
||||
Memo<InfiniteList<T>> tail = Memo.from(() -> this.tail().limit(n - 1));
|
||||
return new InfiniteList<>(head, tail);
|
||||
}
|
||||
|
||||
public InfiniteList<T> takeWhile(Immutator<Boolean, ? super T> pred) {
|
||||
// TODO
|
||||
return new InfiniteList<>(null, null);
|
||||
}
|
||||
|
||||
public List<T> toList() {
|
||||
List<T> arrayList = new ArrayList<>();
|
||||
arrayList.add(this.head());
|
||||
arrayList.addAll(this.tail().toList());
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public <U> U reduce(U id, Combiner<U, U, ? super T> acc) {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
public long count() {
|
||||
// TODO
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + this.head + " " + this.tail + "]";
|
||||
}
|
||||
|
||||
public boolean isEnd() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add your End class here...
|
||||
}
|
||||
Reference in New Issue
Block a user