add lab6
This commit is contained in:
parent
82a1f769fe
commit
cdc460bdc7
24
Lab6/And.java
Normal file
24
Lab6/And.java
Normal file
@ -0,0 +1,24 @@
|
||||
class And implements Cond {
|
||||
private Cond lVal;
|
||||
private Cond rVal;
|
||||
|
||||
public And(Cond lVal, Cond rVal) {
|
||||
this.lVal = lVal;
|
||||
this.rVal = rVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eval() {
|
||||
return this.lVal.eval() && this.rVal.eval();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + this.lVal + " & " + this.rVal + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cond neg() {
|
||||
return new Or(lVal.neg(), rVal.neg());
|
||||
}
|
||||
}
|
24
Lab6/Bool.java
Normal file
24
Lab6/Bool.java
Normal file
@ -0,0 +1,24 @@
|
||||
import cs2030s.fp.Constant;
|
||||
|
||||
class Bool implements Cond {
|
||||
private Boolean val;
|
||||
|
||||
public Bool(Constant<Boolean> val) {
|
||||
this.val = val.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eval() {
|
||||
return this.val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.val.toString().substring(0, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cond neg() {
|
||||
return new Not(this);
|
||||
}
|
||||
}
|
76
Lab6/CS2030STest.java
Normal file
76
Lab6/CS2030STest.java
Normal file
@ -0,0 +1,76 @@
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import javax.tools.DiagnosticCollector;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import javax.tools.ToolProvider;
|
||||
import java.io.PrintStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class CS2030STest {
|
||||
|
||||
private static final String ANSI_RESET = "\u001B[0m";
|
||||
private static final String ANSI_RED = "\u001B[31m";
|
||||
private static final String ANSI_GREEN = "\u001B[32m";
|
||||
|
||||
public void expect(String test, Object output, Object expect) {
|
||||
System.out.print(test);
|
||||
if ((expect == null && output == null) || output.equals(expect)) {
|
||||
System.out.println(".. " + ANSI_GREEN + "ok" + ANSI_RESET);
|
||||
} else {
|
||||
System.out.println(".. " + ANSI_RED + "failed" + ANSI_RESET);
|
||||
System.out.println(" expected: " + expect);
|
||||
System.out.println(" got this: " + output);
|
||||
}
|
||||
}
|
||||
|
||||
public static String clean(String txt) {
|
||||
String res = "";
|
||||
for (int i=0; i<txt.length(); i++) {
|
||||
if (txt.charAt(i) != '\r' && txt.charAt(i) != '\n') {
|
||||
res += txt.charAt(i);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public void expectPrint(String test, Object expect, ByteArrayOutputStream baos, PrintStream old) {
|
||||
System.out.flush();
|
||||
System.setOut(old);
|
||||
expect(test, CS2030STest.clean(baos.toString()), expect);
|
||||
}
|
||||
|
||||
public void expectCompile(String test, String statement, boolean success) {
|
||||
System.out.print(test);
|
||||
|
||||
class JavaSourceFromString extends SimpleJavaFileObject {
|
||||
final String code;
|
||||
|
||||
JavaSourceFromString(String code) {
|
||||
super(URI.create("string:///TempClass.java"), Kind.SOURCE);
|
||||
this.code = "class TempClass {void foo(){" + code + ";}}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
boolean noError = ToolProvider
|
||||
.getSystemJavaCompiler()
|
||||
.getTask(null, null, new DiagnosticCollector<>(), null, null,
|
||||
List.of(new JavaSourceFromString(statement)))
|
||||
.call();
|
||||
|
||||
if (noError != success) {
|
||||
System.out.println(".. " + ANSI_RED + "failed" + ANSI_RESET);
|
||||
if (!success) {
|
||||
System.out.println(" expected compilation error but it compiles fine.");
|
||||
} else {
|
||||
System.out.println(" expected the statement to compile without errors but it does not.");
|
||||
}
|
||||
} else {
|
||||
System.out.println(".. " + ANSI_GREEN + "ok" + ANSI_RESET);
|
||||
}
|
||||
}
|
||||
}
|
4
Lab6/Cond.java
Normal file
4
Lab6/Cond.java
Normal file
@ -0,0 +1,4 @@
|
||||
interface Cond {
|
||||
boolean eval();
|
||||
Cond neg();
|
||||
}
|
19
Lab6/Lab6.h
Normal file
19
Lab6/Lab6.h
Normal file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
mkdir cs2030s
|
||||
cd cs2030s
|
||||
mkdir fp
|
||||
cd ..
|
||||
|
||||
mv Action.java cs2030s/fp/Action.java
|
||||
mv Actionable.java cs2030s/fp/Actionable.java
|
||||
mv Actually.java cs2030s/fp/Actually.java
|
||||
mv Combiner.java cs2030s/fp/Combiner.java
|
||||
mv Constant.java cs2030s/fp/Constant.java
|
||||
mv Immutator.java cs2030s/fp/Immutator.java
|
||||
mv Immutatorable.java cs2030s/fp/Immutatorable.java
|
||||
mv Lazy.java cs2030s/fp/Lazy.java
|
||||
mv Memo.java cs2030s/fp/Memo.java
|
||||
|
||||
javac cs2030s/fp/*.java
|
||||
javac *.java
|
162
Lab6/Lab6.java
Normal file
162
Lab6/Lab6.java
Normal file
@ -0,0 +1,162 @@
|
||||
import cs2030s.fp.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
class Lab6 {
|
||||
public static void main(String[] args) {
|
||||
// Create a scanner to read from standard input.
|
||||
Scanner sc = new Scanner(System.in);
|
||||
|
||||
// Read a single integer from the test file
|
||||
// and then run the appropriate test case
|
||||
switch (sc.nextInt()) {
|
||||
case 1:
|
||||
test1();
|
||||
break;
|
||||
case 2:
|
||||
test2();
|
||||
break;
|
||||
case 3:
|
||||
test3();
|
||||
break;
|
||||
case 4:
|
||||
test4();
|
||||
break;
|
||||
case 5:
|
||||
test5();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void test1() {
|
||||
Lazy<Integer> mod1 = Lazy.from(2030);
|
||||
System.out.println(mod1.toString());
|
||||
|
||||
Lazy<String> mod2 = Lazy.from(() -> "CS2030S");
|
||||
System.out.println(mod2.toString());
|
||||
|
||||
Lazy<String> hello = Lazy.from(() -> {
|
||||
System.out.println("world!");
|
||||
return "hello";
|
||||
});
|
||||
System.out.println(hello.get().toString());
|
||||
System.out.println(hello.get().toString());
|
||||
}
|
||||
|
||||
public static void test2() {
|
||||
Memo<Integer> mod1 = Memo.from(2030);
|
||||
System.out.println(mod1.toString());
|
||||
|
||||
Memo<String> mod2 = Memo.from(() -> "CS2030S");
|
||||
System.out.println(mod2.toString());
|
||||
System.out.println(mod2.get());
|
||||
System.out.println(mod2.toString());
|
||||
|
||||
Memo<String> hello = Memo.from(() -> {
|
||||
System.out.println("world!");
|
||||
return "hello";
|
||||
});
|
||||
System.out.println(hello.get().toString());
|
||||
System.out.println(hello.get().toString());
|
||||
}
|
||||
|
||||
public static void test3() {
|
||||
Constant<String> password = () -> "123456";
|
||||
Lazy<String> lazy = Lazy.from(password);
|
||||
System.out.println(lazy.toString());
|
||||
System.out.println(lazy.transform(str -> str.substring(0, 1)).toString());
|
||||
|
||||
Memo<String> memo = Memo.from(password);
|
||||
System.out.println(memo.toString());
|
||||
System.out.println(memo.transform(str -> str.substring(0, 1)).toString());
|
||||
System.out.println(memo.transform(str -> str.substring(0, 1)).get().toString());
|
||||
System.out.println(memo.toString());
|
||||
|
||||
Immutator<Integer, String> len = str -> {
|
||||
System.out.println("length");
|
||||
return str.length();
|
||||
};
|
||||
Lazy<Integer> lazyLen = lazy.transform(len);
|
||||
System.out.println(lazyLen.toString());
|
||||
System.out.println(lazyLen.get());
|
||||
System.out.println(lazyLen.get());
|
||||
|
||||
Memo<Integer> step1 = Memo.from(1010);
|
||||
Memo<Integer> step2 = step1.transform(i -> i * 2);
|
||||
Memo<Integer> step3 = step2.next(i -> Memo.from(i + 10));
|
||||
System.out.println(step1.toString());
|
||||
System.out.println(step2.toString());
|
||||
System.out.println(step3.toString());
|
||||
System.out.println(step3.get());
|
||||
System.out.println(step2.toString());
|
||||
System.out.println(step1.toString());
|
||||
|
||||
Memo<Integer> noErr = Memo.from(0);
|
||||
Memo<Integer> err = noErr.transform(x -> 1/x);
|
||||
try {
|
||||
System.out.println(err.get());
|
||||
} catch(ArithmeticException ae) {
|
||||
System.out.println(ae.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static void test4() {
|
||||
Combiner<String, Integer, Integer> concat = (x, y) -> {
|
||||
System.out.println("combine");
|
||||
return x.toString() + y.toString();
|
||||
};
|
||||
|
||||
Memo<Integer> twenty, thirty, modInt;
|
||||
twenty = Memo.from(() -> 20);
|
||||
thirty = Memo.from(() -> 30);
|
||||
modInt = twenty.combine(thirty, (x, y) -> x * 100 + y);
|
||||
Memo<String> modStr = twenty.combine(thirty, concat);
|
||||
|
||||
System.out.println(twenty.toString());
|
||||
System.out.println(thirty.toString());
|
||||
System.out.println(modInt.toString());
|
||||
System.out.println(modStr.toString());
|
||||
System.out.println(modStr.get().toString());
|
||||
System.out.println(twenty.toString());
|
||||
System.out.println(thirty.toString());
|
||||
System.out.println(modInt.toString());
|
||||
|
||||
Combiner<String, Integer, Double> comb = (x, y) -> x.toString() + " + " + y.toString();
|
||||
Memo<String> s = modInt.combine(Memo.from(0.1), comb);
|
||||
System.out.println(s.toString());
|
||||
System.out.println(s.get());
|
||||
System.out.println(modInt.toString());
|
||||
|
||||
Memo<Integer> x1 = Memo.from(1);
|
||||
for (int i = 0; i < 10; i ++) {
|
||||
final Memo<Integer> y1 = x1; // final just to ensure it is unchanged
|
||||
final int j = i;
|
||||
x1 = Memo.from(() -> { System.out.println(j); return y1.get() + y1.get(); });
|
||||
}
|
||||
System.out.println(x1.get());
|
||||
}
|
||||
|
||||
public static void test5() {
|
||||
Constant<Boolean> t = new Constant<>() {
|
||||
public Boolean init() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
Constant<Boolean> f = new Constant<>() {
|
||||
public Boolean init() {
|
||||
String res = "";
|
||||
for (int i=0; i<100000; i++) {
|
||||
res += i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Cond cond = new And(new Or(new Bool(t), new Bool(f)), new Not(new Not(new Bool(t))));
|
||||
|
||||
System.out.println(cond.toString());
|
||||
System.out.println(cond.neg().toString());
|
||||
System.out.println(cond.neg().neg().toString());
|
||||
System.out.println(cond.eval());
|
||||
System.out.println(cond.neg().toString());
|
||||
System.out.println(cond.neg().neg().toString());
|
||||
}
|
||||
}
|
BIN
Lab6/Lab6.pdf
Normal file
BIN
Lab6/Lab6.pdf
Normal file
Binary file not shown.
21
Lab6/Not.java
Normal file
21
Lab6/Not.java
Normal file
@ -0,0 +1,21 @@
|
||||
class Not implements Cond {
|
||||
private Cond val;
|
||||
|
||||
public Not(Cond val) {
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eval() {
|
||||
return !this.val.eval();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "!(" + this.val + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cond neg() {
|
||||
return this.val;
|
||||
}
|
||||
}
|
24
Lab6/Or.java
Normal file
24
Lab6/Or.java
Normal file
@ -0,0 +1,24 @@
|
||||
class Or implements Cond {
|
||||
private Cond lVal;
|
||||
private Cond rVal;
|
||||
|
||||
public Or(Cond lVal, Cond rVal) {
|
||||
this.lVal = lVal;
|
||||
this.rVal = rVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eval() {
|
||||
return this.lVal.eval() || this.rVal.eval();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + this.lVal + " | " + this.rVal + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cond neg() {
|
||||
return new And(lVal.neg(), rVal.neg());
|
||||
}
|
||||
}
|
37
Lab6/Test1.java
Normal file
37
Lab6/Test1.java
Normal file
@ -0,0 +1,37 @@
|
||||
import cs2030s.fp.Constant;
|
||||
import cs2030s.fp.Lazy;
|
||||
|
||||
public class Test1 {
|
||||
public static void main(String[] args) {
|
||||
CS2030STest we = new CS2030STest();
|
||||
|
||||
Lazy<Integer> mod1 = Lazy.from(2030);
|
||||
we.expect(
|
||||
"Lazy<Integer> mod1 = Lazy.from(2030)",
|
||||
mod1.toString(),
|
||||
"2030"
|
||||
);
|
||||
|
||||
Lazy<String> mod2 = Lazy.from(() -> "CS2030S");
|
||||
we.expect(
|
||||
"Lazy<String> mod2 = Lazy.from(\"CS2030S\")",
|
||||
mod2.toString(),
|
||||
"CS2030S"
|
||||
);
|
||||
|
||||
Lazy<String> hello = Lazy.from(() -> {
|
||||
System.out.println("world!");
|
||||
return "hello";
|
||||
});
|
||||
we.expect(
|
||||
"hello.get() // warning: we do not check print output",
|
||||
hello.get().toString(),
|
||||
"hello"
|
||||
);
|
||||
we.expect(
|
||||
"hello.get() // warning: we do not check print output",
|
||||
hello.get().toString(),
|
||||
"hello"
|
||||
);
|
||||
}
|
||||
}
|
42
Lab6/Test2.java
Normal file
42
Lab6/Test2.java
Normal file
@ -0,0 +1,42 @@
|
||||
import cs2030s.fp.Constant;
|
||||
import cs2030s.fp.Memo;
|
||||
|
||||
public class Test2 {
|
||||
public static void main(String[] args) {
|
||||
CS2030STest we = new CS2030STest();
|
||||
|
||||
Memo<Integer> mod1 = Memo.from(2030);
|
||||
we.expect(
|
||||
"Memo<Integer> mod1 = Memo.from(2030)",
|
||||
mod1.toString(),
|
||||
"2030"
|
||||
);
|
||||
|
||||
Memo<String> mod2 = Memo.from(() -> "CS2030S");
|
||||
we.expect(
|
||||
"Memo<String> mod2 = Memo.from(\"CS2030S\")",
|
||||
mod2.toString(),
|
||||
"?"
|
||||
);
|
||||
we.expect(
|
||||
"mod2.get()",
|
||||
mod2.get().toString(),
|
||||
"CS2030S"
|
||||
);
|
||||
|
||||
Memo<String> hello = Memo.from(() -> {
|
||||
System.out.println("world!");
|
||||
return "hello";
|
||||
});
|
||||
we.expect(
|
||||
"hello.get() // warning: we do not check print output",
|
||||
hello.get(),
|
||||
"hello"
|
||||
);
|
||||
we.expect(
|
||||
"hello.get() // warning: we do not check print output",
|
||||
hello.get(),
|
||||
"hello"
|
||||
);
|
||||
}
|
||||
}
|
134
Lab6/Test3.java
Normal file
134
Lab6/Test3.java
Normal file
@ -0,0 +1,134 @@
|
||||
import cs2030s.fp.Constant;
|
||||
import cs2030s.fp.Immutator;
|
||||
import cs2030s.fp.Lazy;
|
||||
import cs2030s.fp.Memo;
|
||||
|
||||
public class Test3 {
|
||||
public static void main(String[] args) {
|
||||
CS2030STest we = new CS2030STest();
|
||||
|
||||
Constant<String> password = () -> "123456";
|
||||
Lazy<String> lazy = Lazy.from(password);
|
||||
|
||||
we.expect(
|
||||
"lazy",
|
||||
lazy.toString(),
|
||||
"123456"
|
||||
);
|
||||
we.expect(
|
||||
"lazy.transform(str -> str.substring(0, 1))",
|
||||
lazy.transform(str -> str.substring(0, 1)).toString(),
|
||||
"1"
|
||||
);
|
||||
|
||||
Memo<String> memo = Memo.from(password);
|
||||
we.expect(
|
||||
"memo",
|
||||
memo.toString(),
|
||||
"?"
|
||||
);
|
||||
we.expect(
|
||||
"memo.transform(str -> str.substring(0, 1))",
|
||||
memo.transform(str -> str.substring(0, 1)).toString(),
|
||||
"?"
|
||||
);
|
||||
we.expect(
|
||||
"memo.transform(str -> str.substring(0, 1)).get()",
|
||||
memo.transform(str -> str.substring(0, 1)).get().toString(),
|
||||
"1"
|
||||
);
|
||||
we.expect(
|
||||
"memo",
|
||||
memo.toString(),
|
||||
"123456"
|
||||
);
|
||||
|
||||
Immutator<Integer, String> len = str -> {
|
||||
System.out.println("length");
|
||||
return str.length();
|
||||
};
|
||||
Lazy<Integer> lazyLen = lazy.transform(len);
|
||||
we.expect(
|
||||
"lazyLen // warning: we do not check print output",
|
||||
lazyLen.toString(),
|
||||
"6"
|
||||
);
|
||||
we.expect(
|
||||
"lazyLen.get() // warning: we do not check print output",
|
||||
lazyLen.get(),
|
||||
6
|
||||
);
|
||||
we.expect(
|
||||
"lazyLen.get() // warning: we do not check print output",
|
||||
lazyLen.get(),
|
||||
6
|
||||
);
|
||||
|
||||
Memo<Integer> memoLen = memo.transform(len);
|
||||
we.expect(
|
||||
"memoLen // warning: we do not check print output",
|
||||
memoLen.toString(),
|
||||
"?"
|
||||
);
|
||||
we.expect(
|
||||
"memoLen.get() // warning: we do not check print output",
|
||||
memoLen.get(),
|
||||
6
|
||||
);
|
||||
we.expect(
|
||||
"memoLen.get() // warning: we do not check print output",
|
||||
memoLen.get(),
|
||||
6
|
||||
);
|
||||
|
||||
Memo<Integer> step1 = Memo.from(1010);
|
||||
Memo<Integer> step2 = step1.transform(i -> i * 2);
|
||||
Memo<Integer> step3 = step2.next(i -> Memo.from(i + 10));
|
||||
we.expect(
|
||||
"step1",
|
||||
step1.toString(),
|
||||
"1010"
|
||||
);
|
||||
we.expect(
|
||||
"step2",
|
||||
step2.toString(),
|
||||
"?"
|
||||
);
|
||||
we.expect(
|
||||
"step3",
|
||||
step3.toString(),
|
||||
"?"
|
||||
);
|
||||
we.expect(
|
||||
"step3.get()",
|
||||
step3.get(),
|
||||
2030
|
||||
);
|
||||
we.expect(
|
||||
"step2",
|
||||
step2.toString(),
|
||||
"2020"
|
||||
);
|
||||
we.expect(
|
||||
"step1",
|
||||
step1.toString(),
|
||||
"1010"
|
||||
);
|
||||
|
||||
Memo<Integer> noErr = Memo.from(0);
|
||||
Memo<Integer> err = noErr.transform(x -> 1/x);
|
||||
try {
|
||||
we.expect(
|
||||
"err.get()",
|
||||
err.get(),
|
||||
""
|
||||
);
|
||||
} catch(ArithmeticException ae) {
|
||||
we.expect(
|
||||
"err.get()",
|
||||
ae.getMessage(),
|
||||
"/ by zero"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
92
Lab6/Test4.java
Normal file
92
Lab6/Test4.java
Normal file
@ -0,0 +1,92 @@
|
||||
import cs2030s.fp.Combiner;
|
||||
import cs2030s.fp.Memo;
|
||||
|
||||
public class Test4 {
|
||||
public static void main(String[] args) {
|
||||
CS2030STest we = new CS2030STest();
|
||||
|
||||
Combiner<String, Integer, Integer> concat = (x, y) -> {
|
||||
System.out.println("combine");
|
||||
return x.toString() + y.toString();
|
||||
};
|
||||
|
||||
Memo<Integer> twenty, thirty, modInt;
|
||||
twenty = Memo.from(() -> 20);
|
||||
thirty = Memo.from(() -> 30);
|
||||
modInt = twenty.combine(thirty, (x, y) -> x * 100 + y);
|
||||
Memo<String> modStr = twenty.combine(thirty, concat);
|
||||
|
||||
we.expect(
|
||||
"twenty",
|
||||
twenty.toString(),
|
||||
"?"
|
||||
);
|
||||
we.expect(
|
||||
"thirty",
|
||||
thirty.toString(),
|
||||
"?"
|
||||
);
|
||||
we.expect(
|
||||
"modInt",
|
||||
modInt.toString(),
|
||||
"?"
|
||||
);
|
||||
we.expect(
|
||||
"modStr",
|
||||
modStr.toString(),
|
||||
"?"
|
||||
);
|
||||
|
||||
we.expect(
|
||||
"modStr.get()",
|
||||
modStr.get().toString(),
|
||||
"2030"
|
||||
);
|
||||
|
||||
we.expect(
|
||||
"twenty",
|
||||
twenty.toString(),
|
||||
"20"
|
||||
);
|
||||
we.expect(
|
||||
"thirty",
|
||||
thirty.toString(),
|
||||
"30"
|
||||
);
|
||||
we.expect(
|
||||
"modInt",
|
||||
modInt.toString(),
|
||||
"?"
|
||||
);
|
||||
|
||||
Combiner<String, Integer, Double> comb = (x, y) -> x.toString() + " + " + y.toString();
|
||||
Memo<String> s = modInt.combine(Memo.from(0.1), comb);
|
||||
we.expect(
|
||||
"s",
|
||||
s.toString(),
|
||||
"?"
|
||||
);
|
||||
we.expect(
|
||||
"s.get()",
|
||||
s.get(),
|
||||
"2030 + 0.1"
|
||||
);
|
||||
we.expect(
|
||||
"modInt",
|
||||
modInt.toString(),
|
||||
"2030"
|
||||
);
|
||||
|
||||
Memo<Integer> x1 = Memo.from(1);
|
||||
for (int i = 0; i < 10; i ++) {
|
||||
final Memo<Integer> y1 = x1; // final just to ensure it is unchanged
|
||||
final int j = i;
|
||||
x1 = Memo.from(() -> { System.out.println(j); return y1.get() + y1.get(); });
|
||||
}
|
||||
we.expect(
|
||||
"x.get()",
|
||||
x1.get(),
|
||||
1024
|
||||
);
|
||||
}
|
||||
}
|
55
Lab6/Test5.java
Normal file
55
Lab6/Test5.java
Normal file
@ -0,0 +1,55 @@
|
||||
import cs2030s.fp.Constant;
|
||||
import cs2030s.fp.Memo;
|
||||
|
||||
public class Test5 {
|
||||
public static void main(String[] args) {
|
||||
CS2030STest we = new CS2030STest();
|
||||
|
||||
Constant<Boolean> t = new Constant<>() {
|
||||
public Boolean init() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
Constant<Boolean> f = new Constant<>() {
|
||||
public Boolean init() {
|
||||
String res = "";
|
||||
for (int i=0; i<100000; i++) {
|
||||
res += i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Cond cond = new And(new Or(new Bool(t), new Bool(f)), new Not(new Not(new Bool(t))));
|
||||
|
||||
we.expect(
|
||||
"cond",
|
||||
cond.toString(),
|
||||
"((? | ?) & !(!(?)))"
|
||||
);
|
||||
we.expect(
|
||||
"cond.neg()",
|
||||
cond.neg().toString(),
|
||||
"((!(?) & !(?)) | !(?))"
|
||||
);
|
||||
we.expect(
|
||||
"cond.neg().neg()",
|
||||
cond.neg().neg().toString(),
|
||||
"((? | ?) & ?)"
|
||||
);
|
||||
we.expect(
|
||||
"cond.eval()",
|
||||
cond.eval(),
|
||||
true
|
||||
);
|
||||
we.expect(
|
||||
"cond.neg()",
|
||||
cond.neg().toString(),
|
||||
"((!(t) & !(?)) | !(t))"
|
||||
);
|
||||
we.expect(
|
||||
"cond.neg().neg()",
|
||||
cond.neg().neg().toString(),
|
||||
"((t | ?) & t)"
|
||||
);
|
||||
}
|
||||
}
|
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;
|
||||
}
|
1
Lab6/input/Test1.in
Normal file
1
Lab6/input/Test1.in
Normal file
@ -0,0 +1 @@
|
||||
1
|
1
Lab6/input/Test2.in
Normal file
1
Lab6/input/Test2.in
Normal file
@ -0,0 +1 @@
|
||||
2
|
1
Lab6/input/Test3.in
Normal file
1
Lab6/input/Test3.in
Normal file
@ -0,0 +1 @@
|
||||
3
|
1
Lab6/input/Test4.in
Normal file
1
Lab6/input/Test4.in
Normal file
@ -0,0 +1 @@
|
||||
4
|
1
Lab6/input/Test5.in
Normal file
1
Lab6/input/Test5.in
Normal file
@ -0,0 +1 @@
|
||||
5
|
6
Lab6/output/Test1.out
Normal file
6
Lab6/output/Test1.out
Normal file
@ -0,0 +1,6 @@
|
||||
2030
|
||||
CS2030S
|
||||
world!
|
||||
hello
|
||||
world!
|
||||
hello
|
7
Lab6/output/Test2.out
Normal file
7
Lab6/output/Test2.out
Normal file
@ -0,0 +1,7 @@
|
||||
2030
|
||||
?
|
||||
CS2030S
|
||||
CS2030S
|
||||
world!
|
||||
hello
|
||||
hello
|
19
Lab6/output/Test3.out
Normal file
19
Lab6/output/Test3.out
Normal file
@ -0,0 +1,19 @@
|
||||
123456
|
||||
1
|
||||
?
|
||||
?
|
||||
1
|
||||
123456
|
||||
length
|
||||
6
|
||||
length
|
||||
6
|
||||
length
|
||||
6
|
||||
1010
|
||||
?
|
||||
?
|
||||
2030
|
||||
2020
|
||||
1010
|
||||
/ by zero
|
23
Lab6/output/Test4.out
Normal file
23
Lab6/output/Test4.out
Normal file
@ -0,0 +1,23 @@
|
||||
?
|
||||
?
|
||||
?
|
||||
?
|
||||
combine
|
||||
2030
|
||||
20
|
||||
30
|
||||
?
|
||||
?
|
||||
2030 + 0.1
|
||||
2030
|
||||
9
|
||||
8
|
||||
7
|
||||
6
|
||||
5
|
||||
4
|
||||
3
|
||||
2
|
||||
1
|
||||
0
|
||||
1024
|
6
Lab6/output/Test5.out
Normal file
6
Lab6/output/Test5.out
Normal file
@ -0,0 +1,6 @@
|
||||
((? | ?) & !(!(?)))
|
||||
((!(?) & !(?)) | !(?))
|
||||
((? | ?) & ?)
|
||||
true
|
||||
((!(t) & !(?)) | !(t))
|
||||
((t | ?) & t)
|
Loading…
Reference in New Issue
Block a user