Derive4J - Auto derivation for Functional Java

Derivation of Functional-Java optics and typeclasses via Derive4J API

Лицензия

Лицензия

The GNU General Public License
Категории

Категории

derive4j Универсальные библиотеки Functional Programming
Группа

Группа

org.derive4j
Идентификатор

Идентификатор

derive4j-fj
Последняя версия

Последняя версия

0.2
Дата

Дата

Тип

Тип

jar
Описание

Описание

Derive4J - Auto derivation for Functional Java
Derivation of Functional-Java optics and typeclasses via Derive4J API
Ссылка на сайт

Ссылка на сайт

https://github.com/derive4j/derive4j-fj
Организация-разработчик

Организация-разработчик

Derive4J contributors

Скачать derive4j-fj

Как подключить последнюю версию

<!-- https://jarcasting.com/artifacts/org.derive4j/derive4j-fj/ -->
<dependency>
    <groupId>org.derive4j</groupId>
    <artifactId>derive4j-fj</artifactId>
    <version>0.2</version>
</dependency>
// https://jarcasting.com/artifacts/org.derive4j/derive4j-fj/
implementation 'org.derive4j:derive4j-fj:0.2'
// https://jarcasting.com/artifacts/org.derive4j/derive4j-fj/
implementation ("org.derive4j:derive4j-fj:0.2")
'org.derive4j:derive4j-fj:jar:0.2'
<dependency org="org.derive4j" name="derive4j-fj" rev="0.2">
  <artifact name="derive4j-fj" type="jar" />
</dependency>
@Grapes(
@Grab(group='org.derive4j', module='derive4j-fj', version='0.2')
)
libraryDependencies += "org.derive4j" % "derive4j-fj" % "0.2"
[org.derive4j/derive4j-fj "0.2"]

Зависимости

Библиотека не имеет зависимостей. Это самодостаточное приложение, которое не зависит ни от каких других библиотек.

Модули Проекта

Данный проект не имеет модулей.

FunctionalJava on Derive4J steroids!

This Derive4J extension permits automatic derivation of FunctionalJava instances for the following type classes:

(generation of optics is planned).

So, now, no excuse to write unsafe code that breaks parametricity! ;)

"Implicit" resolution of instances

The implementation of a type class instance may often depends on the instances of the data type fields. Derive4J will try its best to resolve those dependencies for you, following rules similar to scala implicit resolution. In some cases, Derive4J can fail to find a valid instance for a field, for one of the following two reasons:

  • because it does not exist (in the expected classes, ie. its an "orphan instance")
  • or because the instance for that field is not yet generated AND the field type is parametrized.

In both cases you will have to provide a static field or method (in the class of the ADT under derivation) that returns the missing type class instance. The implementation can simply be a forward to a generated instance (for the second case).

Example Usage:

import fj.*;
import org.derive4j.*;

@Data(flavour = Flavour.FJ)
@Derive(@Instances({ Show.class, Hash.class, Equal.class, Ord.class}))
public abstract class Either<A, B> {

  /**
   * The catamorphism for either. Folds over this either breaking into left or right.
   *
   * @param left The function to call if this is left.
   * @param right The function to call if this is right.
   * @return The reduced value.
   */
  public abstract <X> X either(F<A, X> left, F<B, X> right);


  // In case you need to interact with unsafe code that
  // expects hashCode/equal/toString to be implemented:

  @Deprecated
  @Override
  public final boolean equals(Object obj) {
    return Equal.equals0(Either.class, this, obj,
        Eithers.eitherEqual(Equal.anyEqual(), Equal.anyEqual()));
  }

  @Deprecated
  @Override
  public final int hashCode() {
    return Eithers.<A, B>eitherHash(Hash.anyHash(), Hash.anyHash()).hash(this);
  }

  @Deprecated
  @Override
  public final String toString() {
    return Eithers.<A, B>eitherShow(Show.anyShow(), Show.anyShow()).showS(this);
  }
}

Derive4J, through this extension will then derive the following code in the generated Eithers.java file:

  
  public static <A, B> Show<Either<A, B>> eitherShow(Show<A> aShow, Show<B> bShow) {
    return Show.show(either -> either.either(
      (left) -> Stream.fromString("left(").append(() -> aShow.show(left)).append(Stream.fromString(")")),
      (right) -> Stream.fromString("right(").append(() -> bShow.show(right)).append(Stream.fromString(")"))
    ));
  }

  public static <A, B> Ord<Either<A, B>> eitherOrd(Ord<A> aOrd, Ord<B> bOrd) {
    return Ord.ordDef(either1 -> either1.either(
      (left1) -> either2 -> either2.either(
        (left2) -> {
          Ordering o = Ordering.EQ;
          o = aOrd.compare(left1, left2);
          if (o != Ordering.EQ) return o;
          return o;
        },
        (right2) -> Ordering.LT
      ),
      (right1) -> either2 -> either2.either(
        (left2) -> Ordering.GT,
        (right2) -> {
          Ordering o = Ordering.EQ;
          o = bOrd.compare(right1, right2);
          if (o != Ordering.EQ) return o;
          return o;
        }
      )
    ));
  }

  public static <A, B> Equal<Either<A, B>> eitherEqual(Equal<A> aEqual, Equal<B> bEqual) {
    return Equal.equalDef(either1 -> either1.either(
      (left1) -> either2 -> either2.either(
        (left2) -> aEqual.eq(left1, left2),
        (right2) -> false
      ),
      (right1) -> either2 -> either2.either(
        (left2) -> false,
        (right2) -> bEqual.eq(right1, right2)
      )
    ));
  }

  public static <A, B> Hash<Either<A, B>> eitherHash(Hash<A> aHash, Hash<B> bHash) {
    return Hash.hash(either -> either.either(
      (left) -> 23 + aHash.hash(left),
      (right) -> 29 + bHash.hash(right)
    ));
}

Use it in your project

Derive4J-FJ is a "plugin" of Derive4J and should be declared (as well) as a apt/compile-time only dependency (not needed at runtime). So while derive4j and derive4j-fj are (L)GPL-licensed, the generated code is not linked to derive4j, and thus derive4j can be used in any project (proprietary or not). Also you will need jdk8 version of FunctionalJava artifacts (4.7+).

Maven:

<dependency>
    <groupId>org.functionaljava</groupId>
    <artifactId>functionaljava_1.8</artifactId>
    <version>4.7</version>
</dependency>
<dependency>
  <groupId>org.derive4j</groupId>
  <artifactId>derive4j-fj</artifactId>
  <version>0.2</version>
  <optional>true</optional>
</dependency>
<dependency>
  <groupId>org.derive4j</groupId>
  <artifactId>derive4j</artifactId>
  <version>0.12.4</version>
  <optional>true</optional>
</dependency>

Gradle

compile "org.functionaljava:functionaljava_1.8:4.7"
compile(group: 'org.derive4j', name: 'derive4j', version: '0.12.4', ext: 'jar')
compile(group: 'org.derive4j', name: 'derive4j-fj', version: '0.2', ext: 'jar')

or better using the gradle-apt-plugin:

compile "org.functionaljava:functionaljava_1.8:4.7"
compileOnly "org.derive4j:derive4j-annotation:0.12.4"
apt "org.derive4j:derive4j:0.12.4"
apt "org.derive4j:derive4j-fj:0.2"

Contributing

Bug reports, feature requests and pull requests are welcome, as well as contributions to improve documentation.

Contact

jb@giraudeau.info, @jb9i or use the project GitHub issues.

org.derive4j

Версии библиотеки

Версия
0.2
0.1