Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/derive4j/hkt
Higher Kinded Type machinery for Java
https://github.com/derive4j/hkt
annotation-processor functional-programming hk-encoding hkt java-8 typechecker
Last synced: 7 days ago
JSON representation
Higher Kinded Type machinery for Java
- Host: GitHub
- URL: https://github.com/derive4j/hkt
- Owner: derive4j
- License: bsd-3-clause
- Created: 2016-03-24T00:40:16.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2022-02-28T12:03:19.000Z (over 2 years ago)
- Last Synced: 2023-07-28T17:26:46.306Z (over 1 year ago)
- Topics: annotation-processor, functional-programming, hk-encoding, hkt, java-8, typechecker
- Language: Java
- Homepage:
- Size: 205 KB
- Stars: 76
- Watchers: 10
- Forks: 9
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Higher Kinded Type machinery for Java
[![Gitter](https://badges.gitter.im/derive4j/hkt.svg)](https://gitter.im/derive4j/hkt)
[![Maven Central](https://img.shields.io/maven-central/v/org.derive4j.hkt/hkt.svg)][search.maven]
[![Travis](https://travis-ci.org/derive4j/hkt.svg?branch=master)](https://travis-ci.org/derive4j/hkt)This project provides type-safety for the higher kinded type encoding demonstrated in https://github.com/highj/highj via a JSR269 annotation processor.
For some theorical explanation of the encoding you may refer to the [Lightweight higher-kinded polymorphism](https://www.cl.cam.ac.uk/~jdy22/papers/lightweight-higher-kinded-polymorphism.pdf) paper.
# Usage
## Choose your HK encoding:
the two basic possibilities are:
```java
class HkTest implements __, A> {...}
```
and
```java
class HkTest implements __ {
enum w { // could be any name, also could be a static nested class.
}
}
```
We say that `__` is the HK encoding of HkTest and call `w` the *witness type* of `HkTest`.## What about binary type constructors ? Ternary ? And more ?
@derive4j/hkt supplies interfaces `__`, `__2` up to `__9`.
For example, a disjoint union type commonly called "Either" could be declared this way :
```java
class Either implements __2 {
enum µ {}
...
}
```## Obligatory Monad example:
The higher kinded polymorphism gained by the encoding allows us to express things that are normally inexpressible in Java. Eg.:
```java
public interface Monad {
__ pure(A a);default __ map(__ ma, Function f) {
return bind(ma, f.andThen(this::pure));
}
}
```## Aliases interfaces
You may want to create aliases of derive4j hkt `__*` interfaces that better suit your naming preferences, maybe also adding
some default methods. Eg.:```java
interface HigherKind1, T> extends __ {
default R transform(Function<__, R> f) {
return f.apply(this);
}
}
```
And so your hk-encoded classes would look like:
```java
class HkTest implements HigherKind1, A> {...}
```
In any case, just try: if you do something wrong the annotation processor shall help you!## A note on safety : do not cast! Use the generated safe cast methods
By default the annotation processor will generate a `Hkt` class in each package that contains hk-encoded classes.The generated class contains casting methods and factories of [TypeEq](src/main/java/org/derive4j/hkt/TypeEq.java) that allow you to safely recover the original type from its hk-encoding.
Here is an example :
- given the HKT types
```java
class Maybe implements __ {...}
```
and
```java
class List implements __ {...}
```
both in package `myorg.data`- then the following class will be generated
```java
package myorg.data;final class Hkt {
private Hkt() {}
static Maybe asMaybe(final __ hkt) {
return (Maybe) hkt;
}
static List asList(final __ hkt) {
return (List) hkt;
}
}
```Now you may ask : why is that safe ? I could implement `__` in my `Foo` class, pass an instance of it to `Hkt.asMaybe` and then boom !
And to this the answer is no, you can't. That's the whole point of the hkt processor : would you try to implement `__` in any other class than `Maybe`, you'd get a **compile time** error.
The processor thus ensures that the only possible implementation of `__` is `Maybe` : hence the safety of the cast in the generated methods.
## Configuration of code generation
Code generation can be customized by using the [HktConfig](src/main/java/org/derive4j/hkt/HktConfig.java) annotation (on
package-info or classes).Consider the example of the previous section : we would like the generated methods to be called `toX` instead of `asX`. Easy ! Just declare, in the `myorg.data` package, a `package-info` file as such :
```java
@HktConfig(coerceMethodName = "to{ClassName}")
package myorg.data;
```Note that configuration is handled hierarchically through packages, classes and inner classes. That means that would you want to keep your `toX` methods and at the same time have the one for `List` generated in its own class, you could declare a `package-info` as afore mentionned and then annotate the `List` class this way:
```java
@HktConfig(generateIn = "MyHktList")
class List implements __ {...}
```
As expected, the following two files would then be generated :
```java
package myorg.data;final class Hkt {
private Hkt() {}
static Maybe toMaybe(final __ hkt) {
return (Maybe) hkt;
}
}
```
and
```java
package myorg.data;final class MyHktList {
private MyHktList() {}
static List toList(final __ hkt) {
return (List) hkt;
}
}
```## I want it !
### Maven
```xmlorg.derive4j.hkt
hkt
0.9.2```
[search.maven]: http://search.maven.org/#search|ga|1|org.derive4j.hkt### Gradle
```
compile(group: 'org.derive4j.hkt', name: 'hkt', version: '0.9.2', ext: 'jar')
```