简体   繁体   English

Java中如何使用访客模式模拟Haskell的模式匹配

[英]How to simulate Haskell's pattern matching using visitor pattern in Java

I am new to Java and I am trying to use visitor pattern to simulate pattern matching.我是 Java 的新手,我正在尝试使用访客模式来模拟模式匹配。 For this Haskell function为此 Haskell function

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

which returns a value of type a (given a value of type Maybe a and a default value), the following Java codes work.它返回一个 a 类型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);
    }
}

When I try to simulate this function that obtains the "length" of a value of type Maybe [a]当我尝试模拟这个 function 获取Maybe [a]类型值的“长度”时

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

, the Java-version getLength I write is ,我写的 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) { ... }
    });
}

But it doesn't work, since T and List<T> are incompatible.但它不起作用,因为TList<T>不兼容。 How to fix this?如何解决这个问题?

Declare getLength() as a static method with its own type variable:getLength()声明为具有自己的类型变量的 static 方法:

  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) { ... }
    });
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM