This commit is contained in:
Yadunand Prem
2022-09-15 21:07:40 +08:00
committed by Yadunand Prem
parent 4e99493aa5
commit f5a9db22d1
9 changed files with 188 additions and 146 deletions

View File

@@ -1,15 +1,15 @@
/** /**
* The Action interface that can be called * The Action interface that can be called
* on an object of type T to act. * on an object of type T to act.
* *
* Contains a single abstract method call. * Contains a single abstract method call.
* *
* CS2030S Lab 4 * CS2030S Lab 4
* AY22/23 Semester 1 * AY22/23 Semester 1
* *
* @author Yadunand Prem (10B) * @author Yadunand Prem (10B)
*/ */
interface Action<T> { interface Action<T> {
void call(T item) void call(T item);
} }

View File

@@ -1,11 +1,16 @@
/** /**
* The Actionable interface that can * The Actionable interface that can
* act when given an action. * act when given an action.
* *
* Contains a single abstract method act. * Contains a single abstract method act.
* *
* CS2030S Lab 4 * CS2030S Lab 4
* AY22/23 Semester 1 * AY22/23 Semester 1
* *
* @author Put Your Name (Lab Group) * @author Yadunand Prem (10B)
*/ */
// act consumes the T and passes it to action, thus super
interface Actionable<T> {
public void act(Action<? super T> action);
}

View File

@@ -7,5 +7,9 @@
* CS2030S Lab 4 * CS2030S Lab 4
* AY22/23 Semester 1 * AY22/23 Semester 1
* *
* @author Put Your Name (Lab Group) * @author Yadunand Prem (10B)
*/ */
interface Immutator<R,P> {
public R invoke(P param);
}

View File

@@ -8,5 +8,9 @@
* CS2030S Lab 4 * CS2030S Lab 4
* AY22/23 Semester 1 * AY22/23 Semester 1
* *
* @author Put Your Name (Lab Group) * @author Yadunand Prem (10B)
*/ */
interface Immutatorable<T> {
public <R> R transform(Immutator<R, ? super T> immutator);
}

View File

@@ -7,3 +7,10 @@
* *
* @author Put Your Name (Lab Group) * @author Put Your Name (Lab Group)
*/ */
class Improbable<T> implements Immutator<Probably<T>, T> {
@Override
public Probably<T> invoke(T param) {
return Probably.just(param);
}
}

10
Lab4/MyTest.java Normal file
View File

@@ -0,0 +1,10 @@
class MyTest {
public static void main(String[] args) {
Probably<Integer> maybeInt = Probably.just(10);
System.out.println( maybeInt.transform(new Immutator<Integer,Integer>() {
public Integer invoke(Integer t1) {
return t1+1;
}
}));
}
}

View File

@@ -1,18 +1,18 @@
/** /**
* A non-generic Action to print the String * A non-generic Action to print the String
* representation of the object. * representation of the object.
* *
* CS2030S Lab 4 * CS2030S Lab 4
* AY22/23 Semester 1 * AY22/23 Semester 1
* *
* @author Put Your Name (Lab Group) * @author Put Your Name (Lab Group)
*/ */
class Print<T> implements Action<T> { class Print implements Action<Object> {
@Override @Override
public void call(T item) { public void call(Object item) {
System.out.println(item); System.out.println(item);
} }
} }

View File

@@ -1,96 +1,111 @@
/** /**
* This class implements something that * This class implements something that
* probably is just a value but may be nothing. * probably is just a value but may be nothing.
* We will never return null in this class, but * We will never return null in this class, but
* we may return something that contains nothing * we may return something that contains nothing
* where the nothing is a null. * where the nothing is a null.
* *
* @author XXX * @author Yadunand Prem (10B)
* @version CS2030S AY22/23 Semester 1 * @version CS2030S AY22/23 Semester 1
*/ */
class Probably<T> { class Probably<T> implements Actionable<T>, Immutatorable<T> {
private final T value; private final T value;
private static final Probably<?> NONE = new Probably<>(null); private static final Probably<?> NONE = new Probably<>(null);
/** /**
* Private constructor, can only be invoked inside. * Private constructor, can only be invoked inside.
* This is called a factory method. We can only * This is called a factory method. We can only
* create this using the two public static method. * create this using the two public static method.
* *
* @return The shared NOTHING. * @return The shared NOTHING.
*/ */
private Probably(T value) { private Probably(T value) {
this.value = value; this.value = value;
} }
/** /**
* It is probably nothing, no value inside. * It is probably nothing, no value inside.
* *
* @return The shared NOTHING. * @return The shared NOTHING.
*/ */
public static <T> Probably<T> none() { public static <T> Probably<T> none() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Probably<T> res = (Probably<T>) NONE; Probably<T> res = (Probably<T>) NONE;
return res; return res;
} }
/** /**
* It is probably just the given value. * It is probably just the given value.
* Unless the value is null, then nothing is * Unless the value is null, then nothing is
* given again. * given again.
* *
* @param value Probably this is the value * @param value Probably this is the value
* unless it is null then we say * unless it is null then we say
* that there is no * that there is no
* @return The given value or nothing but * @return The given value or nothing but
* never null. * never null.
*/ */
public static <T> Probably<T> just(T value) { public static <T> Probably<T> just(T value) {
if (value == null) { if (value == null) {
return none(); return none();
} }
return (Probably<T>) new Probably<>(value); return new Probably<>(value);
} }
/** /**
* Check for equality between something that * Check for equality between something that
* is probably a value but maybe nothing. * is probably a value but maybe nothing.
* *
* @param obj The other value to be compared. * @param obj The other value to be compared.
* @return True if the two values are equal, * @return True if the two values are equal,
* false otherwise. * false otherwise.
*/ */
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj == this) { if (obj == this) {
return true; return true;
} }
if (obj instanceof Probably<?>) { if (obj instanceof Probably<?>) {
Probably<?> some = (Probably<?>) obj; Probably<?> some = (Probably<?>) obj;
if (this.value == some.value) { if (this.value == some.value) {
return true; return true;
} }
if (this.value == null || some.value == null) { if (this.value == null || some.value == null) {
return false; return false;
} }
return this.value.equals(some.value); return this.value.equals(some.value);
} }
return false; return false;
} }
/** /**
* String representation of something that * String representation of something that
* is probably a value but maybe nothing. * is probably a value but maybe nothing.
* *
* @return The string representation. * @return The string representation.
*/ */
@Override @Override
public String toString() { public String toString() {
if (this.value == null) { if (this.value == null) {
return "<>"; return "<>";
} else { } else {
return "<" + this.value.toString() + ">"; return "<" + this.value.toString() + ">";
} }
} }
}
@Override
public void act(Action<? super T> action) {
if (this.value == null) {
return;
}
action.call(this.value);
}
@Override
public <R> Probably<R> transform(Immutator<Probably<R>, ? super T> immutator) {
return immutator.invoke(this.value);
}
}

View File

@@ -32,11 +32,8 @@ class Test3 {
we.expect("new Improbable<String>().invoke(null)", we.expect("new Improbable<String>().invoke(null)",
new Improbable<String>().invoke(null).toString(), new Improbable<String>().invoke(null).toString(),
"<>"); "<>");
we.expect("new Improbable<Integer>().invoke(1).transform(new Incr())",
new Improbable<Integer>().invoke(1).transform(new Incr()).toString(),
"<2>");
we.expect("new Improbable<>().invoke(new Improbable<>().invoke(1))", we.expect("new Improbable<>().invoke(new Improbable<>().invoke(1))",
new Improbable<>().invoke(new Improbable<Integer>().invoke(1)).toString(), new Improbable<>().invoke(new Improbable<Integer>().invoke(1)).toString(),
"<<1>>"); "<<1>>");
} }
} }