Как имитировать сопоставление с образцом Haskell с использованием образца посетителя в Java - PullRequest
0 голосов
/ 04 августа 2020

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

getOrDefault :: Maybe a -> a -> a
getOrDefault (Just x) = const x
getOrDefault Nothing = id

, которая возвращает значение типа a (с учетом значения типа Maybe a и значения по умолчанию), работают следующие коды Java.

interface Visitor<T, S> {
    S visitJust(Just<T> j);
    S visitNothing(Nothing<T> n);
}

abstract class Maybe<T> {
    public abstract <S> S accept(Visitor<T, S> v);

    public T getOrDefault(T defaultValue) {
        return this.accept(new Visitor<T, T>() {
            @Override
            public T visitJust(Just<T> j) { return j.value; }

            @Override
            public T visitNothing(Nothing<T> n) { return defaultValue; }
        });
    }
}

class Just<T> extends Maybe<T> {
    final T value;

    public Just(T value) {
        this.value = value;
    }

    public <S> S accept(Visitor<T, S> v) {
        return v.visitJust(this);
    }

}

class Nothing<T> extends Maybe<T> {
    public <S> S accept(Visitor<T, S> v) {
        return v.visitNothing(this);
    }
}

Когда я пытаюсь смоделировать эту функцию, которая получает «длину» значения типа Maybe [a]

getLength :: Maybe [a] -> Int
getLength (Just x) = length x
getLength Nothing = -1

, Java -версия getLength я пишу

public int getLength() {
    return this.accept(new Visitor<List<T>, Integer>() {
        @Override
        public Integer visitJust(Just<List<T>> j) { ... }

        @Override
        public Integer visitNothing(Nothing<List<T>> n) { ... }
    });
}

Но это не работает, так как T и List<T> несовместимы. Как это исправить?

1 Ответ

5 голосов
/ 04 августа 2020

Объявить getLength() как метод c stati с собственной переменной типа:

  public static <T> int getLength(Maybe<List<T>> maybe) {
    return maybe.accept(new Visitor<List<T>, Integer>() {
      @Override
      public Integer visitJust(Just<List<T>> j) { ... }

      @Override
      public Integer visitNothing(Nothing<List<T>> n) { ... }
    });
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...