GithubHelp home page GithubHelp logo

functionaljava / functionaljava Goto Github PK

View Code? Open in Web Editor NEW
1.6K 84.0 252.0 3.66 MB

Functional programming in Java

Home Page: www.functionaljava.org

Java 96.86% Scala 3.14%
algebra algebraic-data-types effects functional-programming java monad monoid optics persistent-data-structure property-based-testing

functionaljava's Introduction

Functional Java

Build Status Code Coverage functionaljava

logo 600x144

Functional Java is an open source library facilitating functional programming in Java. The library implements numerous basic and advanced programming abstractions that assist composition oriented development. Functional Java also serves as a platform for learning functional programming concepts by introducing these concepts using a familiar language.

The library is intended for use in production applications and is thoroughly tested using the technique of automated specification-based testing with ScalaCheck and Functional Java’s quickcheck module.

Functional Java provides abstractions for the following types:

  • Basic Data Structures - total and partial functions, products, unit, option, unbiased and right biased unions (either and validation), void.

  • Immutable Collections - array, list, vector, stream, set, map, priority queue, finger tree, heterogenous list, difference list.

  • Other Abstractions - monoid, semigroup, natural, random number generator, reader, writer, state, input/output, parser, zipper, specification based testing (quickcheck), actors, optics (lens, prism, fold, traversal and others), concurrency and type conversion.

Downloading

The recommended way to download and use the project is through your build tool.

The Functional Java artifact is published to Maven Central using the group org.functionaljava with three published artifacts:

  • the core library (functionaljava)

  • property based testing (functionaljava-quickcheck)

  • a small amount of Java 8 support (functionaljava-java-core)

The latest stable version is 5.0. This can be added to your Gradle project by adding the dependencies:

compile "org.functionaljava:functionaljava:5.0"
compile "org.functionaljava:functionaljava-quickcheck:5.0"
compile "org.functionaljava:functionaljava-java-core:5.0"

and in Maven:

<dependency>
    <groupId>org.functionaljava</groupId>
    <artifactId>functionaljava</artifactId>
    <version>5.0</version>
</dependency>
<dependency>
    <groupId>org.functionaljava</groupId>
    <artifactId>functionaljava-quickcheck</artifactId>
    <version>5.0</version>
</dependency>
<dependency>
    <groupId>org.functionaljava</groupId>
    <artifactId>functionaljava-java-core</artifactId>
    <version>5.0</version>
</dependency>

Building

Building is done using Java 8 and Gradle 7.4. In the root directory run:

./gradlew

This requires access to Java 8 and will download the Gradle build tool and necessary dependencies and build FunctionalJava.

Features

A more complete description of the features mentioned above are:

  • Basic Data Structures

    • Functions with arity 1 to 8 (fj.F).

    • Functions with arity 0 to 8 that can produce exceptions (fj.Try).

    • Functions with arity 0 to 8 that have a void return (fj.Effect).

    • Functions with arity 0 to 8 that have a void return and can throw an exception (fj.TryEffect).

    • Products with arity 1 to 8 (fj.P).

    • Unit type (fj.Unit).

    • Optional value - type-safe null (fj.data.Option).

    • Disjoint union data type - compositional exception handling (fj.data.Either).

    • Validation - right biased compositional exception handling (fj.data.Validation).

  • Immutable Collections

    • Array wrapper (fj.data.Array).

    • Immutable, in-memory singly linked list (fj.data.List).

    • Immutable lazy singly linked list (fj.data.Stream).

    • A package (fj.data.fingertrees) providing 2-3 finger trees for a functional representation of persistent sequences, supporting access to the ends in amortized O(1) time.

    • Type-safe heterogeneous list (fj.data.hlist) for lists of elements of differing types without sacrificing type-safety.

    • Immutable set implementation using a red/black tree (fj.data.Set).

    • Immutable multi-way tree - aka rose tree (fj.data.Tree).

    • Immutable tree-map using a red/black tree implementation (fj.data.TreeMap).

    • Immutable priority queue using finger trees (fj.data.PriorityQueue).

    • Difference lists, a highly performant list.

  • Other Abstractions

    • Monoid (fj.Monoid).

    • Semigroup (fj.Semigroup).

    • Natural number data type (fj.data.Natural).

    • Random number generator using a linear congruential generator (fj.LcgRng).

    • Reader, Writer and State monads (fj.data.Reader,fj.data.Writer, fj.data.State).

    • Input/Output monad for abstracting IO (fj.IO).

    • Monadic parser combinators for writing parsers by combining smaller parsers using composition.

    • Conversion of data types to/from standard Java types.

    • Conversion between FunctionalJava and Java 8 specific types.

    • Configurable equality and hash-code for HashMap and HashSet.

    • Zipper implementations for streams and trees.

    • Automated specification-based testing framework (fj.test).

    • Fully operational Actors for parallel computations (fj.control.parallel) and layered abstractions such as parallel-map, map-reduce, parallel-zip.

    • Optics for updating immutable data including lens, prism, iso, optional, traversal, getter, fold and setter. Inspired by the Scala Monocle library (https://github.com/julien-truffaut/Monocle) and the Haskell lens library (https://github.com/ekmett/lens).

    • Void, a logically uninhabited type.

License

The Functional Java license uses the BSD 3 license (3-clause license) available at https://en.wikipedia.org/wiki/BSD_licenses.

Release Notes

For release notes for each version, see the directory link:etc/release-notes.

functionaljava's People

Contributors

amarpotghan avatar bakeemawaytoys avatar chenzhang22 avatar clinuxrulz avatar daneko avatar dobesv avatar drewctaylor avatar drewctaylorgtri avatar fakraemer avatar gliptak avatar gneuvill avatar gpampara avatar jbgi avatar knutwalker avatar l1cache avatar magro avatar martinseeler avatar mperry avatar mrbackend avatar orionll avatar pawelkrupinski avatar pbzdyl avatar puffnfresh avatar retronym avatar rickyclarkson avatar runarorama avatar samekmichal avatar tonymorris avatar toxyduck avatar xuwei-k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

functionaljava's Issues

List.group assumes an already sorted list?

Hi,

Is it normal that List.group assumes that the list is sorted?

System.out.println(List.list("a", "b", "a").group(Equal.stringEqual))

gives

      <<a>,<b>,<a>>

I would have thought it should give

      <<a,a,>,<b>>

Or am I mistaken on the role of the function? If yes, could the documentation be updated then?

Implement immutable Vector, HashMap and HashSet backed by hash tries

While red-black trees are suitable for ordered elements, we also need data structures which can hold elements with no notion of ordering.
We should implement 3 types of immutable collections:

  • Vector - sequence of elements
  • HashSet - set of elements (no repetitions)
  • HashMap - map

These collections can be implemented using hash tries (like in Scala)

Bug in PX.memo()?

Hi,

I'm not exactly sure but I think I found a bug with memo in the PX classes.
Or maybe I'm using it wrongly... I hope not, but if yes, then I don't see how the use case I have should be done with functional java.

When running this code:

public static void main(String[] args) {

    final int i = 5;

    final P3<Integer, Double, String> p = new P3<Integer, Double, String>() {
        @Override
        public Integer _1() {
            return i;
        }

        @Override
        public Double _2() {
            return i*0.2;
        }

        @Override
        public String _3() {
            return "i: "+i;
        }
    };

    p.memo()._3();
}

I get a StackOverflowError:

at fj.F$10$1._1(F.java:203)
at fj.P1$10._1(P1.java:210)
at fj.P3$4._3(P3.java:143)
at fj.P3$7.f(P3.java:182)
at fj.P3$7.f(P3.java:180)
at fj.F$10$1._1(F.java:203)
at fj.P1$10._1(P1.java:210)
at fj.P3$4._3(P3.java:143)
at fj.P3$7.f(P3.java:182)
at fj.P3$7.f(P3.java:180)
at fj.F$10$1._1(F.java:203)
at fj.P1$10._1(P1.java:210)
at fj.P3$4._3(P3.java:143)
at a.Test.main(Test.java:58)

Thanks!

Edit: I simplified the example :)

fj.data.LazyString.toString cause infinite recursion on Android

Context : Android (tested on 5.0.1) with FJ 4.2

Trying to print an Option with :
System.out.println(Option.some(45));

cause an infinite recursion in LazyString.toString :

ERR: stack=java.lang.StackOverflowError: stack size 8MB
            at java.lang.StringBuilder.<init>(StringBuilder.java:81)
            at fj.data.LazyString.toString(LazyString.java:111)
...

it seems the StringBuilder constructor call .toString on CharSequence instead of iterating on the characters, leading to a recursion loop.

TreeMap#split appears broken

I wrote the following test for TreeMap#split and got some unexpected behavior: https://gist.github.com/996438.

It appears the "lesser" and "greater" value sets are being reduced to singleton sets. I looked at the implementation

public P3<Set<V>, Option<V>, Set<V>> split(final K k) {
    final F<Set<P2<K, Option<V>>>, Set<V>> getSome = Option.<V>fromSome().o(P2.<K, Option<V>>__2())
        .mapSet(tree.ord().comap(P.<K, Option<V>>p2().f(k).<V>o(Option.<V>some_())));
    return tree.split(p(k, Option.<V>none())).map1(getSome).map3(getSome)        
        .map2(Option.<V>join().o(P2.<K, Option<V>>__2().mapOption()));
}

and I'm pretty sure the problem is in extrapolating an Ord for values (which may not be comparable at all) from the Ord provided for the keys using a comap. What the current implementation does is map each value v to (k, some(v)), where k is the split key. Unfortunately, the original Ord only considers the first part of the tuple, which is now the constant k for all values. So this comapping effectively makes all values in the set equal, and thus no value inserts after the first one.

Tony on #functionaljava mentioned that TreeMap might have taken some strong implementation cues from Haskell's Data.Map. Here's the signatures for the splits of that structure:

split :: Ord k => k -> Map k a -> (Map k a, Map k a)
splitLookup :: Ord k => k -> Map k a -> (Map k a, Maybe a, Map k a)

I'm happier with this implementation, because we're not returning back sets of values, but rather submaps, so we don't have to deal with having an Ord for values at all.

If you guys are in agreement of how to resolve this, I can put together a pull request with the fix and necessary tests.

Parser.StreamParser.satisfyOpt

I wrote this. Seems useful. Is this something y'all want in the library?

    public static <I, O, E> Parser<Stream<I>, O, E> satisfyOpt(final P1<E> missing, final F<I, E> sat,
                                                               final F<I, Option<O>> f) {
        return Parser.StreamParser.<I, E>element(missing).bind(new F<I, Parser<Stream<I>, O, E>>() {
            @Override
            public Parser<Stream<I>, O, E> f(final I i) {
                return f.f(i).option(Parser.<Stream<I>, O, E>fail(sat.f(i)), new F<O, Parser<Stream<I>, O, E>>() {
                    @Override
                    public Parser<Stream<I>, O, E> f(final O o) {
                        return value(o);
                    }
                });
            }
        });
    }

`Property.check` doesn't propagate exceptions from `Gen`s

I don't have a minimal test case or anything, but I think this bug is pretty clear:

https://github.com/functionaljava/functionaljava/blob/master/core/src/main/java/fj/test/Property.java#L187

public CheckResult check(final Rand r,
                           final int minSuccessful,
                           final int maxDiscarded,
                           final int minSize,
                           final int maxSize) {
    int s = 0;
    int d = 0;
    float sz = minSize;
    CheckResult res;

    while (true) {
      final float size = s == 0 && d == 0 ? minSize : sz + (maxSize - sz) / (minSuccessful - s);
      try {
        final Result x = f.f(round(size)).f(r);
        if (x.isNoResult())
          if (d + 1 >= maxDiscarded) {
            res = exhausted(s, d + 1);
            break;
          } else {
            sz = size;
            d++;
          }
        else if (x.isProven()) {
          res = proven(x.args().some(), s + 1, d);
          break;
        } else if (x.isUnfalsified())
          if (s + 1 >= minSuccessful) {
            res = passed(s + 1, d);
            break;
          } else {
            sz = size;
            s++;
          }
        else if (x.isFalsified()) {
          res = falsified(x.args().some(), s, d);
          break;
        } else if (x.isException()) {
          res = propException(x.args().some(), x.exception().some(), s, d);
          break;
        }
      } catch (final Throwable t) {
        genException(t, s, d); // <= result is discarded
      }
    }

    return res;
  }

if a throwable is caught, it is swallowed silently and the while loop continues on.

Provide equals/hashCode/toString for fj.List<A>

fj.List should provide a default implementation of equals, hashCode and toString that uses the .equals(), .hashCode() and .toString() implementations of its members. For instance, this equality check on the same list contents currently fails:

public class TestList { 
    public static void main( String[] args ) { 
        final java.util.List<Integer> myList = Arrays.asList( 1, 2, 3 ); 
        boolean equal = iterableList( myList ).equals( iterableList( myList ) ); 
        System.out.println( "equal = " + equal );//prints false 
    } 
} `

Discussion of this topic was provided here:
https://groups.google.com/forum/?fromgroups#!topic/functionaljava/qc5fUHOg0AU

P1.memo() sometimes returns null when accessed concurrently

Paweł Krupiński reported an issue in the group as per below (https://groups.google.com/forum/#!topic/functionaljava/nSPIBAvAWVY):

Hi.
We started noticing NullPointerExceptions in our code that accessed fj.data.Stream instances concurrently.

I was able to trace it down to P1.memo() creating a P1 that sometimes returns null from ._1() call when accessed concurrently.
Here's how to reproduce it (sometimes you need to run it multiple times) on Java 8 and functionaljava 4.2:

final P1<String> p1 = P.p("Bla").memo();
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 1000; i++) {
    executorService.submit(() -> {
        if (p1._1() == null) {
            System.out.println("Null");
        }
    });
}

executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.DAYS);

A falsified test with a null parameter causes a NullPointerException

Test case:

    @Test
    public void testShowNullParameters() {
Arbitrary.arbInteger.gen))), (Integer i) -> {
        Property p = property(arbitrary(Gen.<Integer>value(null)), (Integer i) -> {
                return prop(i != null);
        });
        CheckResult.summary.println(p.check());
    }

Exception stack:

java.lang.NullPointerException
    at fj.Show$3.f(Show.java:183)
    at fj.Show$3.f(Show.java:180)
    at fj.Show.show(Show.java:63)
    at fj.Show.showS(Show.java:83)
    at fj.test.Arg$1.f(Arg.java:57)
    at fj.test.Arg$1.f(Arg.java:55)
    at fj.Show$2.f(Show.java:169)
    at fj.Show$2.f(Show.java:167)
    at fj.Show.show(Show.java:63)
    at fj.Show.showS(Show.java:83)
    at fj.test.CheckResult$1.arguments(CheckResult.java:236)
    at fj.test.CheckResult$1.f(CheckResult.java:247)
    at fj.test.CheckResult$1.f(CheckResult.java:229)
    at fj.Show$2.f(Show.java:169)
    at fj.Show$2.f(Show.java:167)
    at fj.Show.show(Show.java:63)
    at fj.Show.print(Show.java:129)
    at fj.Show.println(Show.java:115)
    at fj.data.test.TestNull.testShowNullParameters(TestNull.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

Does not compile in eclipse

It seems like functionaljava is a great test case for the Java 8 compiler. I filed a bug with eclipse, and I thought I would put a link to there from here in case someone else runs into the same issues, basically marking this as a known issue with functionaljava in eclipse.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=461004

Note that if you are just using the functionaljava jar files this is not an issue.

Wrong samples imports

In some samples appear imports like this:

import static fj.pre.Show.intShow;
import static fj.pre.Show.listShow;

I think that right imports should be like this:

import static fj.Show.intShow;
import static fj.Show.listShow;

Support for higher order type polymorphism

Does @functionaljava rules out any support for higher order type polymorphism?
(ie, like how it is done in https://github.com/DanielGronau/highj/wiki)
If yes, what about about a safer, closed-world implementation via GADT, something like:

/**
 * A 'GADT' for "lifting" a type constructors to type parameter level in order to allow the simulation of higher order type
 * polymorphism.
 */
public abstract class h<X, T> {

  private h() {
  }

  private static abstract class Types<R, X, T> {
    R option(final Option<T> option) {
      throw Bottom.undefined();
    }

    R p1(final P1<T> p1) {
      throw Bottom.undefined();
    }

    // ... all generic types we care about
  }

  abstract <R> R match(Types<R, X, T> types);

  public static <T> h<Option<?>, T> option(final Option<T> option) {
    return new h<Option<?>, T>() {
      @Override
      <R> R match(final Types<R, Option<?>, T> types) {
        return types.option(option);
      }
    };
  }

  public static <T> Option<T> narrow(final h<Option<?>, T> hOption) {
    return hOption.match(new Types<Option<T>, Option<?>, T>() {
      @Override
      Option<T> option(final Option<T> option) {
        return option;
      }
    });
  }

}
public abstract class Monad<X> {

  public abstract <A> h<X, A> pure(A a);

  public abstract <A, B> h<X, B> bind(h<X, A> ha, F<A, h<X, B>> f);

}

  public static final Monad<Option<?>> monad = new Monad<Option<?>>() {

    @Override
    public <A> h<Option<?>, A> pure(final A a) {
      return h.option(some(a));
    }

    @Override
    public <A, B> h<Option<?>, B> bind(final h<Option<?>, A> ha, final F<A, h<Option<?>, B>> f) {
      return h.option(h.narrow(ha).bind(a -> h.narrow(f.f(a))));
    }
  };

Some.toString causes stackoverflow on Android

Option.some("").toString() results in StackOverflowException.

This means assertEquals can't be used in JUnit tests with Options because attempts by that framework to generate an assert failure message result in stack overflow.

java.lang.StackOverflowError
at fj.data.LazyString.toString(LazyString.java:111)
at java.lang.StringBuilder.<init>(StringBuilder.java:81)
....
at fj.data.LazyString.toString(LazyString.java:111)
at java.lang.StringBuilder.<init>(StringBuilder.java:81)
at fj.data.Stream.asString(Stream.java:1049)
at fj.Show.showS(Show.java:83)
at fj.data.Option.toString(Option.java:51)

fj.data.Java#EnumSet_List throws ClassCastException

Test code

import fj.Show;
import fj.data.Java;
import fj.data.List;

import java.util.EnumSet;

import static fj.Show.listShow;

public class Test {
  public static void main(final String[] args) {
    final List<Colors> colors = Java.<Colors>EnumSet_List().f(EnumSet.allOf(Colors.class));
    listShow(Show.<Colors>anyShow()).print(colors);
  }

  enum Colors {
    red, green, blue
  }
}

Output

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Enum;
    at fj.data.Java$77.f(Java.java:1781)
    at fj.data.Java$77.f(Java.java:1778)
    at fj.demo.Test.main(Test.java:13)

The problematic part is this: (A[]) new Object[as.size()]

Many more functions in fj.data.Java use this idiom.

Add toString for P2 to P8

Use the Show.pxShow methods to add toString methods to the classes P2 to P8. P1 is an interface, so toString will have to be added to P1Functions (unfortunately this limits it's usefulness).

Equals.shallowEqualsO may be wrong for non-final class

and thus all Object.equals() implementation that use it in classes that allow subclassing. Pull request to fix this is on the way.
The following test fails:

  @Test
  public void equals() throws Exception {
    P1<Integer> p1a = new P1<Integer>() {

      @Override
      public Integer _1() {
        return 1;
      }
    };
    P1<Integer> p1b = new P1<Integer>() {

      @Override
      public Integer _1() {
        return 1;
      }
    };

    org.junit.Assert.assertTrue(p1a + " and " + p1b + " should be equal by Object.equals", p1a.equals(p1b));
  }

Collections name conflict with standard library

Actually it is quite frustrating, that common collections names confilct with standard java collections names, e.g. List, HashMap - so you have to use fully qualified names when using both. Isn't it a good idea to give them a prefix for example ListF, HashMapF? (like it is in bolts library - https://bitbucket.org/stepancheg/bolts/src/c91e8b36dc22c92021a055ad183c96c9f734b884/src/main/java/ru/yandex/bolts/collection/?at=trunk)

I understand that these changes are not backward-compatible, but it is not so difficult to refactor though.

Fails to compile under version 8 updates 20 and 25

Compilation in Java 1.8.0_20 and 25 triggers a JDK compiler bug as per below.

:demo:compileJava
An exception has occurred in the compiler (1.8.0_25). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.NullPointerException
at com.sun.tools.javac.code.Types.isConvertible(Types.java:290)
at com.sun.tools.javac.comp.Check.assertConvertible(Check.java:922)
at com.sun.tools.javac.comp.Check.checkMethod(Check.java:876)
at com.sun.tools.javac.comp.Attr.checkMethod(Attr.java:3838)
at com.sun.tools.javac.comp.Attr.checkIdInternal(Attr.java:3615)
at com.sun.tools.javac.comp.Attr.checkMethodIdInternal(Attr.java:3522)
at com.sun.tools.javac.comp.Attr.checkMethodId(Attr.java:3501)
at com.sun.tools.javac.comp.Attr.checkId(Attr.java:3488)
at com.sun.tools.javac.comp.Attr.visitSelect(Attr.java:3370)
at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1897)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.visitApply(Attr.java:1843)
at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1465)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.attribExpr(Attr.java:649)
at com.sun.tools.javac.comp.Attr.visitVarDef(Attr.java:1093)
at com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:852)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676)
at com.sun.tools.javac.comp.Attr.attribStats(Attr.java:692)
at com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:1142)
at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:909)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676)
at com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:1035)
at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:778)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676)
at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:4342)
at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4252)
at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4181)
at com.sun.tools.javac.comp.Attr.attrib(Attr.java:4156)
at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1248)
at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
at org.gradle.api.internal.tasks.compile.jdk6.Jdk6JavaCompiler.execute(Jdk6JavaCompiler.java:45)
at org.gradle.api.internal.tasks.compile.jdk6.Jdk6JavaCompiler.execute(Jdk6JavaCompiler.java:38)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors(NormalizingJavaCompiler.java:96)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:49)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:35)
at org.gradle.api.internal.tasks.compile.DelegatingJavaCompiler.execute(DelegatingJavaCompiler.java:29)
at org.gradle.api.internal.tasks.compile.DelegatingJavaCompiler.execute(DelegatingJavaCompiler.java:20)
at org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute(CleaningJavaCompilerSupport.java:33)
at org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute(CleaningJavaCompilerSupport.java:24)
at org.gradle.api.tasks.compile.JavaCompile.performCompilation(JavaCompile.java:87)
at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:65)
at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.doExecute(AnnotationProcessingTaskFactory.java:235)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.execute(AnnotationProcessingTaskFactory.java:222)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:200)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:296)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:23)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:86)
at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67)
at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:54)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:148)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:105)
at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:85)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:81)
at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:33)
at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:24)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:39)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:29)
at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:50)
at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:171)
at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:237)
at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:210)
at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35)
at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:206)
at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
at org.gradle.launcher.Main.doAction(Main.java:33)
at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:54)
at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:35)
at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.gradle.wrapper.BootstrapMainStarter.start(BootstrapMainStarter.java:30)
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:127)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:55)
:demo:compileJava FAILED

Implement Predicate<T>

many times I ended up in writing following combinators, I think it would add some value if library has it :

  1. F<A, Bool> and(F<A, Bool> pred1, F<A, Bool> pred2)
  2. F<A, Bool> or(F<A, Bool> pred1, F<A, Bool> pred2)
  3. F < B, Bool > comap(F<B, A>, F<A, Bool>)
  4. F<B, Bool> notFor(F<B, A>, F<A, Bool>) [a la Haskell's Data.Function.Predicate's isn't]
  5. F<A, Bool> inverse(F<A, Bool>)

additionally we could add:
nand, nor, xor
We can also implement Predicate2<A, B>, Predicate3<A, B, C> and so on.
thoughts?

Why not use git tags?

It would be great if this project adopted the practice of pushing a (git tag)[http://learn.github.com/p/tagging.html] for each released version -- it makes it super easy to go to the source version that corresponds to a released version.

It's such a simple step, and it would be a great help to us users of the library.

TreeZipper.findChild => Error: head on empty stream

Hi,

There seems to be a bug in the inner function 'split' declared in 'TreeZipper.findChild'. Indeed, the sub condition 'xs.isNotEmpty()' does not prevent a recursive call to f with an empty stream as the second argument : in this very case, the first call to 'xs.head()' explodes.

Hope that helps,

G.N

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.