# HG changeset patch
# User tatsuki
# Date 1426853043 -32400
# Node ID fe80c1edf1be8bf032ce6b4058ffbad5a5009b85
add getLoop
diff -r 000000000000 -r fe80c1edf1be src/main/java/fj/Bottom.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/fj/Bottom.java Fri Mar 20 21:04:03 2015 +0900
@@ -0,0 +1,109 @@
+package fj;
+
+/**
+ * Represents the bottom _|_ value.
+ *
+ * @version %build.number%
+ */
+public final class Bottom {
+ private Bottom() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns an error to represent undefinedness in a computation.
+ *
+ * @return An error to represent undefinedness in a computation.
+ */
+ public static Error undefined() {
+ return error("undefined");
+ }
+
+ /**
+ * Returns an error to represent undefinedness in a computation with early failure using the given
+ * message.
+ *
+ * @param s The message to fail with.
+ * @return An error to represent undefinedness in a computation with early failure using the given
+ * message.
+ */
+ public static Error error(final String s) {
+ throw new Error(s);
+ }
+
+ /**
+ * Provides a thunk that throws an error using the given message when evaluated.
+ *
+ * @param s The message to fail with.
+ * @return A thunk that throws an error using the given message when evaluated.
+ */
+ public static P1 error_(final String s) {
+ return new P1() {
+ @Override public A _1() {
+ throw new Error(s);
+ }
+ };
+ }
+
+ /**
+ * Provides a function that throws an error using the given message, ignoring its argument.
+ *
+ * @param s The message to fail with.
+ * @return A function that throws an error using the given message, ignoring its argument.
+ */
+ public static F errorF(final String s) {
+ return new F() {
+ public B f(final A a) {
+ throw new Error(s);
+ }
+ };
+ }
+
+ /**
+ * Represents a deconstruction failure that was non-exhaustive.
+ *
+ * @param a The value being deconstructed.
+ * @param sa The rendering for the value being deconstructed.
+ * @return A deconstruction failure that was non-exhaustive.
+ */
+ public static Error decons(final A a, final Show sa) {
+ return error("Deconstruction failure on type " + a.getClass() + " with value " + sa.show(a).toString());
+ }
+
+ /**
+ * Represents a deconstruction failure that was non-exhaustive.
+ *
+ * @param c The type being deconstructed.
+ * @return A deconstruction failure that was non-exhaustive.
+ */
+ @SuppressWarnings({"UnnecessaryFullyQualifiedName"})
+ public static Error decons(final java.lang.Class c) {
+ return error("Deconstruction failure on type " + c);
+ }
+
+ /**
+ * A function that returns the toString
for a throwable.
+ *
+ * @return A function that returns the toString
for a throwable.
+ */
+ public static F eToString() {
+ return new F() {
+ public String f(final Throwable t) {
+ return t.toString();
+ }
+ };
+ }
+
+ /**
+ * A function that returns the getMessage
for a throwable.
+ *
+ * @return A function that returns the getMessage
for a throwable.
+ */
+ public static F eMessage() {
+ return new F() {
+ public String f(final Throwable t) {
+ return t.getMessage();
+ }
+ };
+ }
+}
diff -r 000000000000 -r fe80c1edf1be src/main/java/fj/Class.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/fj/Class.java Fri Mar 20 21:04:03 2015 +0900
@@ -0,0 +1,135 @@
+package fj;
+
+import fj.data.List;
+import static fj.data.List.unfold;
+import fj.data.Option;
+import static fj.data.Option.none;
+import static fj.data.Option.some;
+import fj.data.Tree;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+/**
+ * A wrapper for a {@link java.lang.Class} that provides additional methods.
+ *
+ * @version %build.number%
+ */
+public final class Class {
+ private final java.lang.Class c;
+
+ private Class(final java.lang.Class c) {
+ this.c = c;
+ }
+
+ /**
+ * Returns the inheritance hierarchy of this class.
+ *
+ * @return The inheritance hierarchy of this class.
+ */
+ public List> inheritance() {
+ return unfold(
+ new F, Option, java.lang.Class super T>>>>() {
+ public Option, java.lang.Class super T>>> f(
+ final java.lang.Class super T> c) {
+ if (c == null)
+ return none();
+ else {
+ final P2, java.lang.Class super T>> p =
+ new P2, java.lang.Class super T>>() {
+ public java.lang.Class super T> _1() {
+ return c;
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public java.lang.Class super T> _2() {
+ return c.getSuperclass();
+ }
+ };
+ return some(p);
+ }
+ }
+ }, c).map(new F, Class super T>>() {
+ public Class super T> f(final java.lang.Class super T> c) {
+ return clas(c);
+ }
+ });
+ }
+
+ /**
+ * Provides this class's type parameter information as a Tree of the type expression.
+ * Only descends into Parameterized classes. Non-abstract classes, or classes that don't implement an interface,
+ * are treated as raw types. Arrays, Type Variables, and Wildcards are treated as opaque Types.
+ *
+ * @return The rose tree representing the type expression for this class.
+ */
+ public Tree classParameters() {
+ return typeParameterTree(c);
+ }
+
+ /**
+ * Provides this class's superclass type parameter information as a Tree of the type expression.
+ * Only descends into Parameterized classes. Non-abstract classes, or classes that don't implement an interface,
+ * are treated as raw types. Arrays, Type Variables, and Wildcards are treated as opaque Types.
+ *
+ * @return The Tree representing the type expression for this class's superclass.
+ */
+ public Tree superclassParameters() {
+ return typeParameterTree(c.getGenericSuperclass());
+ }
+
+ /**
+ * Provides this class's interface type parameter information as a list of trees.
+ *
+ * @return A list of trees representing the type expressions for this class's interfaces.
+ */
+ public List> interfaceParameters() {
+ List> ts = List.nil();
+ for (final Type t : c.getInterfaces()) {
+ ts = ts.snoc(typeParameterTree(t));
+ }
+ return ts;
+ }
+
+ /**
+ * Provides type parameter information as a Tree of the type expression.
+ * Only descends into Parameterized classes. Non-abstract classes, or classes that don't implement an interface,
+ * are treated as raw types. Arrays, Type Variables, and Wildcards are treated as opaque Types.
+ *
+ * @param t The type (class) for which to get the generic type information.
+ * @return Type parameter information as a rose tree of the type expression.
+ */
+ public static Tree typeParameterTree(final Type t) {
+ List> typeArgs = List.nil();
+ final Tree types;
+ if (t instanceof ParameterizedType) {
+ final ParameterizedType pt = (ParameterizedType) t;
+ for (final Type arg : pt.getActualTypeArguments()) {
+ typeArgs = typeArgs.snoc(typeParameterTree(arg));
+ }
+ types = Tree.node(pt.getRawType(), typeArgs);
+ } else {
+ types = Tree.node(t, List.>nil());
+ }
+ return types;
+ }
+
+ /**
+ * Returns the underlying class.
+ *
+ * @return The underlying class.
+ */
+ public java.lang.Class clas() {
+ return c;
+ }
+
+ /**
+ * Constructs a class from the given argument.
+ *
+ * @param c The argument to construct this class with.
+ * @return A class from the given argument.
+ */
+ public static Class clas(final java.lang.Class c) {
+ return new Class(c);
+ }
+}
diff -r 000000000000 -r fe80c1edf1be src/main/java/fj/Digit.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/fj/Digit.java Fri Mar 20 21:04:03 2015 +0900
@@ -0,0 +1,211 @@
+package fj;
+
+import fj.data.Option;
+import static fj.data.Option.some;
+import static fj.data.Option.none;
+
+/**
+ * The digits zero to nine.
+ *
+ * @version %build.number%
+ */
+public enum Digit {
+ /**
+ * Zero.
+ */
+ _0,
+
+ /**
+ * One.
+ */
+ _1,
+
+ /**
+ * Two.
+ */
+ _2,
+
+ /**
+ * Three.
+ */
+ _3,
+
+ /**
+ * Four.
+ */
+ _4,
+
+ /**
+ * Five.
+ */
+ _5,
+
+ /**
+ * Six.
+ */
+ _6,
+
+ /**
+ * Seven.
+ */
+ _7,
+
+ /**
+ * Eight.
+ */
+ _8,
+
+ /**
+ * Nine.
+ */
+ _9;
+
+ /**
+ * Converts this digit to a long.
+ *
+ * @return A long for this digit.
+ */
+ public long toLong() {
+ switch (this) {
+ case _0:
+ return 0L;
+ case _1:
+ return 1L;
+ case _2:
+ return 2L;
+ case _3:
+ return 3L;
+ case _4:
+ return 4L;
+ case _5:
+ return 5L;
+ case _6:
+ return 6L;
+ case _7:
+ return 7L;
+ case _8:
+ return 8L;
+ default:
+ return 9L;
+ }
+ }
+
+ /**
+ * Converts this digit to a character.
+ *
+ * @return A character for this digit.
+ */
+ public char toChar() {
+ switch (this) {
+ case _0:
+ return '0';
+ case _1:
+ return '1';
+ case _2:
+ return '2';
+ case _3:
+ return '3';
+ case _4:
+ return '4';
+ case _5:
+ return '5';
+ case _6:
+ return '6';
+ case _7:
+ return '7';
+ case _8:
+ return '8';
+ default:
+ return '9';
+ }
+ }
+
+ /**
+ * Converts the right-most digit in the given long value to a digit.
+ *
+ * @param i The long to convert.
+ * @return The right-most digit in the given long value as a digit.
+ */
+ public static Digit fromLong(final long i) {
+ final long x = Math.abs(i) % 10L;
+ return x == 0L ? _0 :
+ x == 1L ? _1 :
+ x == 2L ? _2 :
+ x == 3L ? _3 :
+ x == 4L ? _4 :
+ x == 5L ? _5 :
+ x == 6L ? _6 :
+ x == 7L ? _7 :
+ x == 8L ? _8 :
+ _9;
+ }
+
+ /**
+ * Converts the given character in the given long value to a digit.
+ *
+ * @param c The character to convert.
+ * @return The character in the given long value as a digit.
+ */
+ public static Option fromChar(final char c) {
+ switch (c) {
+ case '0':
+ return some(_0);
+ case '1':
+ return some(_1);
+ case '2':
+ return some(_2);
+ case '3':
+ return some(_3);
+ case '4':
+ return some(_4);
+ case '5':
+ return some(_5);
+ case '6':
+ return some(_6);
+ case '7':
+ return some(_7);
+ case '8':
+ return some(_8);
+ case '9':
+ return some(_9);
+ default:
+ return none();
+ }
+ }
+
+ /**
+ * First-class conversion from digit to a long.
+ */
+ public static final F toLong = new F() {
+ public Long f(final Digit d) {
+ return d.toLong();
+ }
+ };
+
+ /**
+ * First-class conversion from a long to a digit.
+ */
+ public static final F fromLong = new F() {
+ public Digit f(final Long i) {
+ return fromLong(i);
+ }
+ };
+
+ /**
+ * First-class conversion from a digit to a character.
+ */
+ public static final F toChar = new F() {
+ public Character f(final Digit d) {
+ return d.toChar();
+ }
+ };
+
+ /**
+ * First-class conversion from a character to a digit.
+ */
+ public static final F> fromChar = new F>() {
+ public Option f(final Character c) {
+ return fromChar(c);
+ }
+ };
+}
diff -r 000000000000 -r fe80c1edf1be src/main/java/fj/Effect.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/fj/Effect.java Fri Mar 20 21:04:03 2015 +0900
@@ -0,0 +1,113 @@
+package fj;
+
+import fj.function.Effect0;
+import fj.function.Effect1;
+import fj.function.Effect2;
+import fj.function.Effect3;
+import fj.function.Effect4;
+import fj.function.Effect5;
+import fj.function.Effect6;
+import fj.function.Effect7;
+import fj.function.Effect8;
+
+import static fj.Unit.unit;
+
+/**
+ * Represents a side-effect.
+ *
+ * @version %build.number%
+ */
+public class Effect {
+
+ private Effect() {}
+
+ public static P1 f(Effect0 e) {
+ return P.lazy(u -> unit());
+ }
+
+ /**
+ * Returns a function for the given effect.
+ *
+ * @return The function using the given effect.
+ */
+ public static final F f(Effect1 e1) {
+ return a -> {
+ e1.f(a);
+ return unit();
+ };
+ }
+
+ public static F2 f(Effect2 e) {
+ return (a, b) -> {
+ e.f(a, b);
+ return unit();
+ };
+ }
+
+ public static F3 f(Effect3 e) {
+ return (a, b, c) -> {
+ e.f(a, b, c);
+ return unit();
+ };
+ }
+
+ public static F4 f(Effect4 e) {
+ return (a, b, c, d) -> {
+ e.f(a, b, c, d);
+ return unit();
+ };
+ }
+
+ public static F5 f(Effect5 z) {
+ return (a, b, c, d, e) -> {
+ z.f(a, b, c, d, e);
+ return unit();
+ };
+ }
+
+ public static F6 f(Effect6 z) {
+ return (a, b, c, d, e, f) -> {
+ z.f(a, b, c, d, e, f);
+ return unit();
+ };
+ }
+
+ public static F7 f(Effect7 z) {
+ return (a, b, c, d, e, f, g) -> {
+ z.f(a, b, c, d, e, f, g);
+ return unit();
+ };
+ }
+
+ public static F8 f(Effect8 z) {
+ return (a, b, c, d, e, f, g, h) -> {
+ z.f(a, b, c, d, e, f, g, h);
+ return unit();
+ };
+ }
+
+ /**
+ * A contra-variant functor on effect.
+ *
+ * @param f The function to map over the effect.
+ * @return An effect after a contra-variant map.
+ */
+ public final Effect1 comap(Effect1 e1, final F f) {
+ return new Effect1() {
+ public void f(final B b) {
+ e1.f(f.f(b));
+ }
+ };
+ }
+
+ public static Effect1 lazy(final F f) {
+ return new Effect1() {
+ public void f(final A a) {
+ f.f(a);
+ }
+ };
+ }
+
+// public static void f(Effect1 )
+
+}
diff -r 000000000000 -r fe80c1edf1be src/main/java/fj/Equal.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/fj/Equal.java Fri Mar 20 21:04:03 2015 +0900
@@ -0,0 +1,667 @@
+package fj;
+
+import static fj.Function.curry;
+
+import fj.data.*;
+import fj.data.hlist.HList;
+import fj.data.vector.V2;
+import fj.data.vector.V3;
+import fj.data.vector.V4;
+import fj.data.vector.V5;
+import fj.data.vector.V6;
+import fj.data.vector.V7;
+import fj.data.vector.V8;
+
+import java.math.BigInteger;
+import java.math.BigDecimal;
+
+/**
+ * Tests for equality between two objects.
+ *
+ * @version %build.number%
+ */
+public final class Equal {
+ private final F> f;
+
+ private Equal(final F> f) {
+ this.f = f;
+ }
+
+ /**
+ * Returns true
if the two given arguments are equal, false
otherwise.
+ *
+ * @param a1 An object to test for equality against another.
+ * @param a2 An object to test for equality against another.
+ * @return true
if the two given arguments are equal, false
otherwise.
+ */
+ public boolean eq(final A a1, final A a2) {
+ return f.f(a1).f(a2);
+ }
+
+ /**
+ * First-class equality check.
+ *
+ * @return A function that returns true
if the two given arguments are equal.
+ */
+ public F2 eq() {
+ return new F2() {
+ public Boolean f(final A a, final A a1) {
+ return eq(a, a1);
+ }
+ };
+ }
+
+ /**
+ * Partially applied equality check.
+ *
+ * @param a An object to test for equality against another.
+ * @return A function that returns true
if the given argument equals the argument to this method.
+ */
+ public F eq(final A a) {
+ return new F() {
+ public Boolean f(final A a1) {
+ return eq(a, a1);
+ }
+ };
+ }
+
+ /**
+ * Maps the given function across this equal as a contra-variant functor.
+ *
+ * @param f The function to map.
+ * @return A new equal.
+ */
+ public Equal comap(final F f) {
+ return equal(F1Functions.o(F1Functions.o(F1Functions.andThen(f), this.f), f));
+ }
+
+ /**
+ * Constructs an equal instance from the given function.
+ *
+ * @param f The function to construct the equal with.
+ * @return An equal instance from the given function.
+ */
+ public static Equal equal(final F> f) {
+ return new Equal(f);
+ }
+
+ /**
+ * Returns an equal instance that uses the {@link Object#equals(Object)} method to test for
+ * equality.
+ *
+ * @return An equal instance that uses the {@link Object#equals(Object)} method to test for
+ * equality.
+ */
+ public static Equal anyEqual() {
+ return new Equal(new F>() {
+ public F f(final A a1) {
+ return new F() {
+ public Boolean f(final A a2) {
+ return a1.equals(a2);
+ }
+ };
+ }
+ });
+ }
+
+ /**
+ * An equal instance for the boolean
type.
+ */
+ public static final Equal booleanEqual = anyEqual();
+
+ /**
+ * An equal instance for the byte
type.
+ */
+ public static final Equal byteEqual = anyEqual();
+
+ /**
+ * An equal instance for the char
type.
+ */
+ public static final Equal charEqual = anyEqual();
+
+ /**
+ * An equal instance for the double
type.
+ */
+ public static final Equal doubleEqual = anyEqual();
+
+ /**
+ * An equal instance for the float
type.
+ */
+ public static final Equal floatEqual = anyEqual();
+
+ /**
+ * An equal instance for the int
type.
+ */
+ public static final Equal intEqual = anyEqual();
+
+ /**
+ * An equal instance for the BigInteger
type.
+ */
+ public static final Equal bigintEqual = anyEqual();
+
+ /**
+ * An equal instance for the BigDecimal
type.
+ */
+ public static final Equal bigdecimalEqual = anyEqual();
+
+ /**
+ * An equal instance for the long
type.
+ */
+ public static final Equal longEqual = anyEqual();
+
+ /**
+ * An equal instance for the short
type.
+ */
+ public static final Equal shortEqual = anyEqual();
+
+ /**
+ * An equal instance for the {@link String} type.
+ */
+ public static final Equal stringEqual = anyEqual();
+
+ /**
+ * An equal instance for the {@link StringBuffer} type.
+ */
+ public static final Equal stringBufferEqual =
+ new Equal(new F>() {
+ public F f(final StringBuffer sb1) {
+ return new F() {
+ public Boolean f(final StringBuffer sb2) {
+ if (sb1.length() == sb2.length()) {
+ for (int i = 0; i < sb1.length(); i++)
+ if (sb1.charAt(i) != sb2.charAt(i))
+ return false;
+ return true;
+ } else
+ return false;
+ }
+ };
+ }
+ });
+
+ /**
+ * An equal instance for the {@link StringBuilder} type.
+ */
+ public static final Equal stringBuilderEqual =
+ new Equal(new F>() {
+ public F f(final StringBuilder sb1) {
+ return new F() {
+ public Boolean f(final StringBuilder sb2) {
+ if (sb1.length() == sb2.length()) {
+ for (int i = 0; i < sb1.length(); i++)
+ if (sb1.charAt(i) != sb2.charAt(i))
+ return false;
+ return true;
+ } else
+ return false;
+ }
+ };
+ }
+ });
+
+ /**
+ * An equal instance for the {@link Either} type.
+ *
+ * @param ea Equality across the left side of {@link Either}.
+ * @param eb Equality across the right side of {@link Either}.
+ * @return An equal instance for the {@link Either} type.
+ */
+ public static Equal> eitherEqual(final Equal ea, final Equal eb) {
+ return new Equal>(new F, F, Boolean>>() {
+ public F, Boolean> f(final Either e1) {
+ return new F, Boolean>() {
+ public Boolean f(final Either e2) {
+ return e1.isLeft() && e2.isLeft() && ea.f.f(e1.left().value()).f(e2.left().value()) ||
+ e1.isRight() && e2.isRight() && eb.f.f(e1.right().value()).f(e2.right().value());
+ }
+ };
+ }
+ });
+ }
+
+ /**
+ * An equal instance for the {@link Validation} type.
+ *
+ * @param ea Equality across the failing side of {@link Validation}.
+ * @param eb Equality across the succeeding side of {@link Validation}.
+ * @return An equal instance for the {@link Validation} type.
+ */
+ public static Equal> validationEqual(final Equal ea, final Equal eb) {
+ return eitherEqual(ea, eb).comap(Validation.either());
+ }
+
+ /**
+ * An equal instance for the {@link List} type.
+ *
+ * @param ea Equality across the elements of the list.
+ * @return An equal instance for the {@link List} type.
+ */
+ public static Equal> listEqual(final Equal ea) {
+ return new Equal>(new F, F, Boolean>>() {
+ public F, Boolean> f(final List a1) {
+ return new F, Boolean>() {
+ public Boolean f(final List a2) {
+ List x1 = a1;
+ List x2 = a2;
+
+ while (x1.isNotEmpty() && x2.isNotEmpty()) {
+ if (!ea.eq(x1.head(), x2.head()))
+ return false;
+
+ x1 = x1.tail();
+ x2 = x2.tail();
+ }
+
+ return x1.isEmpty() && x2.isEmpty();
+ }
+ };
+ }
+ });
+ }
+
+ /**
+ * An equal instance for the {@link NonEmptyList} type.
+ *
+ * @param ea Equality across the elements of the non-empty list.
+ * @return An equal instance for the {@link NonEmptyList} type.
+ */
+ public static Equal> nonEmptyListEqual(final Equal ea) {
+ return listEqual(ea).comap(NonEmptyList.toList_());
+ }
+
+ /**
+ * An equal instance for the {@link Option} type.
+ *
+ * @param ea Equality across the element of the option.
+ * @return An equal instance for the {@link Option} type.
+ */
+ public static Equal