Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import tester.*;
- // Represents functions of signature A -> R, for some argument type A and
- // result type R
- interface IFunc<A, R> {
- R apply(A input);
- }
- interface IFunc2<A1, A2, R> {
- R apply(A1 arg1, A2 arg2);
- }
- class Sum implements IFunc2<Integer, Integer, Integer> {
- @Override
- public Integer apply(Integer arg1, Integer arg2) {
- return arg1 + arg2;
- }
- }
- // generic list
- interface IList<T> {
- // map over a list, and produce a new list with a (possibly different)
- // element type
- <U> IList<U> map(IFunc<T, U> f);
- <U> U foldr(IFunc2<T, U, U> f, U base);
- IList<T> add(T t);
- }
- // empty generic list
- class MtList<T> implements IList<T> {
- public <U> IList<U> map(IFunc<T, U> f) {
- return new MtList<U>();
- }
- public IList<T> add(T t) {
- return new ConsList<T>(t, this);
- }
- @Override
- public <U> U foldr(IFunc2<T, U, U> f, U base) {
- return base;
- }
- }
- // non-empty generic list
- class ConsList<T> implements IList<T> {
- T first;
- IList<T> rest;
- ConsList(T first, IList<T> rest) {
- this.first = first;
- this.rest = rest;
- }
- public <U> IList<U> map(IFunc<T, U> f) {
- return new ConsList<U>(f.apply(this.first), this.rest.map(f));
- }
- public IList<T> add(T t) {
- return new ConsList<T>(this.first, this.rest.add(t));
- }
- @Override
- public <U> U foldr(IFunc2<T, U, U> f, U base) {
- return f.apply(this.first, this.rest.foldr(f, base));
- }
- }
- //a json value
- interface JSON {
- <T> T accept(JSONVisitor<T> visitor);
- }
- //no value
- class JSONBlank implements JSON {
- public <T> T accept(JSONVisitor<T> visitor) {
- return visitor.visitBlank(this);
- }
- }
- //a number
- class JSONNumber implements JSON {
- int number;
- JSONNumber(int number) {
- this.number = number;
- }
- public <T> T accept(JSONVisitor<T> visitor) {
- return visitor.visitNumber(this);
- }
- }
- //a boolean
- class JSONBool implements JSON {
- boolean bool;
- JSONBool(boolean bool) {
- this.bool = bool;
- }
- public <T> T accept(JSONVisitor<T> visitor) {
- return visitor.visitBool(this);
- }
- }
- //a string
- class JSONString implements JSON {
- String str;
- JSONString(String str) {
- this.str = str;
- }
- public <T> T accept(JSONVisitor<T> visitor) {
- return visitor.visitString(this);
- }
- }
- //a list of JSON values
- class JSONList implements JSON {
- IList<JSON> values;
- JSONList(IList<JSON> values) {
- this.values = values;
- }
- public <T> T accept(JSONVisitor<T> visitor) {
- return visitor.visitList(this);
- }
- }
- interface JSONVisitor<T> extends IFunc<JSON, T> {
- T visitBlank(JSONBlank blank);
- T visitNumber(JSONNumber number);
- T visitBool(JSONBool bool);
- T visitString(JSONString string);
- T visitList(JSONList list);
- }
- class JSONToNumberVisitor implements JSONVisitor<Integer> {
- @Override
- public Integer apply(JSON input) {
- return input.accept(this);
- }
- @Override
- public Integer visitBlank(JSONBlank blank) {
- return 0;
- }
- @Override
- public Integer visitNumber(JSONNumber number) {
- return number.number;
- }
- @Override
- public Integer visitBool(JSONBool bool) {
- return bool.bool ? 1 : 0;
- }
- @Override
- public Integer visitString(JSONString string) {
- return string.str.length();
- }
- public Integer visitList(JSONList list) {
- IFunc2<Integer, Integer, Integer> sum = new Sum();
- return list.values.map(this).foldr(sum, 0);
- }
- }
- class examplesJSON {
- JSON blank = new JSONBlank();
- JSON number1 = new JSONNumber(1);
- JSON number15 = new JSONNumber(15);
- JSON boolTrue = new JSONBool(true);
- JSON boolFalse = new JSONBool(false);
- JSON string5 = new JSONString("abcde");
- JSON string3 = new JSONString("abc");
- IList<JSON> mtJsonList = new MtList<JSON>();
- IList<JSON> littleList = mtJsonList.add(string5).add(number1).add(blank).add(boolFalse);
- JSON list = new JSONList(littleList);
- IList<JSON> jsonList = mtJsonList.add(blank).add(number1).add(number15).add(boolTrue)
- .add(boolFalse).add(string3).add(string5).add(list);
- IList<Integer> answer = new MtList<Integer>().add(0).add(1).add(15).add(1).add(0).add(3).add(5).add(6);
- IList<Integer> numList = new MtList<Integer>().add(0).add(1).add(2).add(3);
- IFunc2<Integer, Integer, Integer> sum = new Sum();
- JSONVisitor<Integer> visitor = new JSONToNumberVisitor();
- void testVisitor(Tester t) {
- t.checkExpect(jsonList.map(visitor), answer);
- t.checkExpect(numList.foldr(sum, 0), 6);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement