All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.mperry.fg.SimpleIO Maven / Gradle / Ivy

There is a newer version: 0.8
Show newest version
package com.github.mperry.fg;

import fj.F;
import fj.Unit;
import fj.control.Trampoline;
import fj.control.parallel.Strategy;
import fj.data.Stream;
import groovy.transform.TypeChecked;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Created with IntelliJ IDEA.
 * User: MarkPerry
 * Date: 7/11/13
 * Time: 11:47 AM
 * To change this template use File | Settings | File Templates.
 */
public abstract class SimpleIO {

    public abstract A run();

    public  SimpleIO append(final SimpleIO io) {
        return new SimpleIO() {
            @Override
            public B run() {
                SimpleIO.this.run();
                return io.run();
            }
        };
    }

    public  SimpleIO append1(final SimpleIO io) {
        return new SimpleIO() {
            @Override
            public A run() {
                A a = SimpleIO.this.run();
                io.run();
                return a;
            }
        };
    }

	public  SimpleIO map(final F f) {
		return new SimpleIO() {
			public B run() {
                A a = SimpleIO.this.run();
				B b = f.f(a);
                return b;
			}
		};
	}


	public  SimpleIO flatMap(final F> f) {
		return new SimpleIO() {
			public B run() {
                A a = SimpleIO.this.run();
                SimpleIO sb = f.f(a);
                B b = sb.run();
                return b;
			}
		};
	}

    public  SimpleIO flatMap1(final F> f) {
        return new SimpleIO() {
            public A run() {
                A a = SimpleIO.this.run();
                f.f(a).run();
                return a;
            }
        };
    }

	static public  SimpleIO lift(final B b) {
		return new SimpleIO() {
			public B run() {
				return b;
			}
		};
	}

    public SimpleIO> gparsPromise() {
        final SimpleIO self = this;
        return new SimpleIO>() {
            @Override
            public groovyx.gpars.dataflow.Promise run() {
                return SimpleIOExtension.asyncGpars(self);
            }
        };
    }

    public SimpleIO> fjPromise() {
        final SimpleIO self = this;
        return new SimpleIO>() {
            @Override
            public fj.control.parallel.Promise run() {
                return SimpleIOExtension.asyncFj(self);
            }
        };
    }

    public SimpleIO> future() {
        // the service needs to be shutdown or the program will not terminate
        return future(defaultService());
    }

    public SimpleIO> future(final ExecutorService service) {
        final SimpleIO self = this;
        return new SimpleIO>() {
            @Override
            public Future run() {
                return SimpleIOExtension.asyncJava(self, service);
            }
        };
    }

    public static Strategy defaultStrategy() {
        return Strategy.simpleThreadStrategy();
    }

    public static ExecutorService defaultService() {
        // the service needs to be shutdown or the program will not terminate
        return Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
    }

    public static  Trampoline>> transform(final SimpleIO>>> io) {
        SimpleIO> io2 = new SimpleIO>() {
              @Override
              public Stream run() {
                  return io.run().run().run();
              }
        };
        return Trampoline.pure(io2);
    }

    static  SimpleIO> sequenceWhile(final Stream> stream, final F f) {
        return new SimpleIO>() {
            @Override
            public Stream run() {
                boolean loop = true;
                Stream> input = stream;
                Stream result = Stream.nil();
                while (loop) {
                    if (input.isEmpty()) {
                        loop = false;
                    } else {
                        A a = input.head().run();
                        if (!f.f(a)) {
                            loop = false;
                        } else {
                            input = input.tail()._1();
                            result = result.cons(a);
                        }
                    }
                }
                return result.reverse();
            }
        };
    }

}