(I'm not sure about Java) I thought it would be nice to support direct sum types by default. I also made a "interpreter that calculates reverse Polish notation formulas (such as1 2 +
= 3
) "for studying using direct sum types.
package neta;
import java.util.Stack;
public class Main {
//A type that represents a numerical type
static class IntType extends Exception {
int v;
IntType(int v) {
this.v = v;
}
@Override
public String toString() {
return Integer.toString(v);
}
}
//A type that represents a positive operation
static class PlusOperation extends Exception {
@Override
public String toString() {
return "+";
}
}
private static void eval(String statement) throws IntType, PlusOperation {
try {
throw new IntType(Integer.parseInt(statement));
} catch (NumberFormatException e) {
if (statement.equals("+")) {
throw new PlusOperation();
} else {
//Use Stack to calculate Reverse Polish Notation
Stack<Integer> stack = new Stack<>();
//Tokens can be separated by spaces
for (String s : statement.split(" ")) {
try {
eval(s);
} catch (IntType iv) {
stack.push(iv.v);
} catch (PlusOperation op) {
stack.push(stack.pop() + stack.pop());
}
}
throw new IntType(stack.pop());
}
}
}
private static void test(String statement) {
try {
eval(statement);
} catch (IntType | PlusOperation e) {
System.out.println(e);
}
}
public static void main(String[] args) {
test("1");
test("1 2 +");
test("3 4 + 5 +");
test("6 7 8 + +");
test("+");
}
}
Running this program will produce the following output:
1
3
12
21
+
It seems that the throws
keyword is used in the function definition to indicate the return type.
//Example
void eval(String statement) throws IntType, PlusOperation
In this example, the direct sum type of ʻIntType and
PlusOperation is the return type of the ʻeval ()
function.
It's cool to write the return type after the function name, like in modern programming languages (Go / Rust / ..).
I'm not sure that the keyword that represents a function is void
, but I think it's grammatically based on the latest language trends.
It seems to use the throw
keyword when returning a value. I think many programming languages use keywords like return
, but that's rare.
//Example:Returns a numeric type
throw new IntType(Integer.parseInt(statement));
//Example:Returns the addition operator
throw new PlusOperation();
Note that when returning a value, you must make it an instance of a class with ʻextends Exception, such as ʻIntType
, or you will get a compile error. It's a little troublesome.
Use try / catch
to conditional branch according to type. It's like Scala or a modern language match / case.
try {
eval(s);
} catch (IntType iv) {
//Processing according to type
} catch (PlusOperation op) {
//Processing according to type
}
In a language with history, it seems that it uses a visitor pattern, or it looks up the type and branches with something like ʻinstanceof`.
Like the Go language, it seems to get a compile error if you don't check the returned error.
try {
throw new IntType(Integer.parseInt(statement));
} catch (NumberFormatException e) {
//What to do if an error type value is returned
}
In the above, you can write normal processing at once, and you do not have to check the return value error one by one, so it is like a monad.
Recommended Posts