英文:
How to simulate Haskell's pattern matching using visitor pattern in Java
问题
// Java代码示例
// 以下是用于模拟Haskell函数和Visitor模式的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; }
});
}
public abstract int getLength();
}
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);
}
public int getLength() {
// 在这里实现获取长度的逻辑
// 返回合适的长度值
}
}
class Nothing<T> extends Maybe<T> {
public <S> S accept(Visitor<T, S> v) {
return v.visitNothing(this);
}
public int getLength() {
// 返回表示没有长度的值,比如 -1
return -1;
}
}
// 解决泛型问题
// 要解决类型不匹配的问题,您需要将Visitor接口的泛型参数类型设置为List<T>,而不仅仅是T。
// 这样,Visitor中的方法就能正确地匹配Just<List<T>>和Nothing<List<T>>的类型。
public int getLength() {
return this.accept(new Visitor<List<T>, Integer>() {
@Override
public Integer visitJust(Just<List<T>> j) {
List<T> list = j.value;
return list.size();
}
@Override
public Integer visitNothing(Nothing<List<T>> n) {
return -1;
}
});
}
请注意,由于这是一个简化的示例,您可能需要根据您的实际需求进行适当的调整和扩展。此代码演示了如何使用Visitor模式在Java中实现类似于Haskell中的模式匹配功能。
英文:
I am new to Java and I am trying to use visitor pattern to simulate pattern matching. For this 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.
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]
getLength :: Maybe [a] -> Int
getLength (Just x) = length x
getLength Nothing = -1
, the Java-version getLength
I write is
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. How to fix this?
答案1
得分: 4
声明 getLength()
作为一个带有自己类型变量的静态方法:
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) { ... }
});
}
英文:
Declare getLength()
as a static method with its own type variable:
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) { ... }
});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论