Java - заменить тип интерфейса для типа реализации параметрами ограниченного типа

Я пытаюсь изучить функциональное программирование с помощью Haskell, но я изо всех сил пытаюсь понять некоторые концепции. Я подумал, что было бы неплохо перевести некоторые из этих концепций на Java, так как это язык, с которым я чувствую себя наиболее комфортно.

У меня есть следующий интерфейс Applicative<A>:

public interface Applicative<A>
{
    public <B> Applicative<B> pure (B value);

    public <B> Applicative<B> apply (Applicative<Function<A, B>> applicative);

    public <B, C> Function<Applicative<B>, Applicative<C>> liftA2 (
        Function<A, Function<B, C>> function);
}

Допустим, у меня есть реализация интерфейса ListApplicative<A>. Он расширяет ArrayList<A> и реализует Applicative<A>.

Вопрос: как мне превратить все Applicative<?> в ListApplicative<?>? Это вообще возможно? Есть ли какие-нибудь хаки, чтобы сделать это?

public class ListApplicative<A> extends ArrayList<A> implements Applicative<A>
{
    @Override
    public <B> ListApplicative<B> pure (B value)
    {
        // Implementation
    }

    @Override
    public <B> ListApplicative<B> apply (
        ListApplicative<Function<A, B>> applicative)
    {
        // Implementation
    }

    @Override
    public <B, C> Function<ListApplicative<B>, ListApplicative<C>> liftA2 (
        Function<A, Function<B, C>> function)
    {
        // Implementation
    }
}

Я немного читал о типах с F-привязкой, но я не уверен, что делать. Я не могу использовать B или C в качестве параметризованных типов, поскольку их типы неизвестны, пока вы не запустите функцию.

Я просмотрел другие подобные вопросы, такие как это о функторах, этот о дженериках дженериков и этот вопрос об интерфейсах, но я не нашел ответа, который искал.

Большое спасибо!


person PaperMonoid    schedule 27.12.2017    source источник
comment
Почему вы хотите превратить Applicative<?> в ListApplicative<?>? Ваш интерфейс предназначен для работы с Applicative<?>, поэтому вы должны гарантировать, что весь ваш класс, реализующий Applicative<?>, может работать с Applicative<?>, а не только с ListApplicative<?>. Если вы действительно хотите это сделать, вам не следует использовать интерфейс, просто напишите эти методы в своем классе ListApplicative<?>.   -  person zhh    schedule 27.12.2017
comment
Я слышал сравнение между классами типов Haskell и интерфейсами Java, поэтому подумал, что это хороший подход.   -  person PaperMonoid    schedule 27.12.2017
comment
Извините, я плохо знаю Haskell. Насколько я знаю, вы не можете сделать это в Java, это не проблема дженериков или классов типов, но это нарушает основную идею interface. Вы можете использовать instanceof, чтобы проверить, является ли Applicative<?> ListApplicative<?>, и вы также можете вернуть ListApplicative<?> как Applicative<?>, но при таком подходе вы не получите преимущества статических проверок компиляции.   -  person zhh    schedule 27.12.2017