-
Notifications
You must be signed in to change notification settings - Fork 253
Open
Description
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))));
}
};Metadata
Metadata
Assignees
Labels
No labels