Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functors in Java

I'm trying to define classes in Java that are similar to Haskell's functors. Hereby, a functor is defined as:

/**
 * Programming languages allow only (just simply enough) endofunctor, that are functors from and to the same category.
 * In this case, the category is the one of the datatypes (in here Type, in order to make it more clear)
 */
public interface EndoFunctor<X extends Type> extends Type {

    /**
     * The basic implementation for any element fx
     * @param map   Transformation function for the type parameter
     * @param fx    Element of the current class
     * @param <Y>   Target type
     * @return      transformed element through map
     */
    <Y extends Type> EndoFunctor<Y> fmap(Function<X,Y> map, EndoFunctor<X> fx);

}

If I want to implement a Identity Functor over types functor, I have to write something like

public class Id<X extends Type> implements EndoFunctor<X> {
    protected X witness;
    Id(X witness) { this.witness = witness; }
    @Override
    public <Y extends Type> Id<Y> fmap(Function<X, Y> map, Id<X> fx) {
        return new Id<>(map.apply(fx.witness));
    }
}

The problem with this code is that Id<X> does not match the type EndoFunctor<X>. How could I determine fmap in the EndoFunctor interface such that if any type K<T> implements EndoFunctor<T> and a map function T->U is given, then K<U> is returned as a value, without any typecasting (that is, since I know that my object is an Id<T>, then the result of fmap "has to be" a Id<U>, and hence I downcast the result of type EndoFunctor<U> to such type)?

like image 835
jackb Avatar asked Jun 04 '16 13:06

jackb


People also ask

What is the use of functors?

A functor (or function object) is a C++ class that acts like a function. Functors are called using the same old function call syntax. To create a functor, we create a object that overloads the operator().

What are functors in functional programming?

In functional programming, a functor is a design pattern inspired by the definition from category theory, that allows for a generic type to apply a function inside without changing the structure of the generic type. This idea is encoded in Haskell using type class.

What are function objects in Java?

In computer programming, a function object is a construct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax (a function parameter that can also be a function). Function objects are often called functors.

Are arrays functors?

An array is a good example of a functor, but many other kinds of objects can be mapped over as well, including promises, streams, trees, objects, etc. JavaScript's built in array and promise objects act like functors.


1 Answers

You could use CRTP:

interface EndoFunctor<X extends Type, T extends EndoFunctor<X, T>> extends Type {
    <Y extends Type> EndoFunctor<Y, ?> fmap(Function<X,Y> map, T fx);    
}

class Id<X extends Type> implements EndoFunctor<X, Id<X>> {
    protected X witness;
    Id(X witness) { this.witness = witness; }

    @Override
    public <Y extends Type> Id<Y> fmap(Function<X, Y> map, Id<X> fx) {
        return new Id<>(map.apply(fx.witness));
    }
}
like image 183
Jorn Vernee Avatar answered Oct 08 '22 19:10

Jorn Vernee