Vavr 列表中的模式匹配对象分解
Pattern matching object decomposition on list in Vavr
是否有任何选项可以在 vavrs 集合上应用对象分解?
即类似于 scala 中的代码片段:
val x = List(1, 2, 3)
val t = x match {
case List(a, b, c) => (a, b, c)
}
(在本例中我们将列表转换为元组)
我在这里看到了一些与我的案例类似的例子 https://github.com/vavr-io/vavr/issues/1157 但看起来当前的语法不同或者甚至是不可能的。
Vavr 列表与许多函数式程序一样,由头部(单个元素,称为 Cons)和尾部(另一个列表)组成,可以匹配第一个元素(不是最后一个,除非通过反转列表),尽管这将比 Scala/Haskell 更冗长。此外,虽然您可以匹配前 3 个元素,但您只能捕获第一个元素:
var t = Match(x).of(
Case($Cons($(), $Cons($(), $Cons($(), $()))), (a, tail) -> Tuple(a, tail.head(), x.get(2)))
);
Vavr documentation of Pattern Matching and its limitations:
The current API makes the compromise that all patterns are matched but
only the root patterns are decomposed.
编辑:如果你想要列表中正好有 3 个元素,那么你需要确保第三个元素之后的尾部是一个空列表(称为 Nil):
var t = Match(x).of(
Case($Cons($(), $Cons($(), $Cons($(), $Nil()))), (a, tail) -> Tuple(a, tail.head(), x.get(2)))
);
JMPL 是简单的 java 库,它可以模拟一些特征模式匹配,使用 Java 8 个特征。
这个库也支持解构模式
Figure figure = new Rectangle();
let(figure, (int w, int h) -> {
System.out.println("border: " + w + " " + h));
});
matches(figure).as(
Rectangle.class, (int w, int h) -> System.out.println("square: " + (w * h)),
Circle.class, (int r) -> System.out.println("square: " + (2 * Math.PI * r)),
Else.class, () -> System.out.println("Default square: " + 0)
);
foreach(listRectangles, (int w, int h) -> {
System.out.println("square: " + (w * h));
});
Deconstruct 类 必须有一个或多个提取方法。
它们必须被标记为注解@Extract。参数必须是
输出。由于原始类型和原始类型的包装器不能
通过引用传递我们必须使用包装器,如 IntRef、FloatRef 等。
@Extract
public void deconstruct(IntRef width, IntRef height) {
width.set(this.width);
height.set(this.height);
}
是否有任何选项可以在 vavrs 集合上应用对象分解?
即类似于 scala 中的代码片段:
val x = List(1, 2, 3)
val t = x match {
case List(a, b, c) => (a, b, c)
}
(在本例中我们将列表转换为元组)
我在这里看到了一些与我的案例类似的例子 https://github.com/vavr-io/vavr/issues/1157 但看起来当前的语法不同或者甚至是不可能的。
Vavr 列表与许多函数式程序一样,由头部(单个元素,称为 Cons)和尾部(另一个列表)组成,可以匹配第一个元素(不是最后一个,除非通过反转列表),尽管这将比 Scala/Haskell 更冗长。此外,虽然您可以匹配前 3 个元素,但您只能捕获第一个元素:
var t = Match(x).of(
Case($Cons($(), $Cons($(), $Cons($(), $()))), (a, tail) -> Tuple(a, tail.head(), x.get(2)))
);
Vavr documentation of Pattern Matching and its limitations:
The current API makes the compromise that all patterns are matched but only the root patterns are decomposed.
编辑:如果你想要列表中正好有 3 个元素,那么你需要确保第三个元素之后的尾部是一个空列表(称为 Nil):
var t = Match(x).of(
Case($Cons($(), $Cons($(), $Cons($(), $Nil()))), (a, tail) -> Tuple(a, tail.head(), x.get(2)))
);
JMPL 是简单的 java 库,它可以模拟一些特征模式匹配,使用 Java 8 个特征。 这个库也支持解构模式
Figure figure = new Rectangle();
let(figure, (int w, int h) -> {
System.out.println("border: " + w + " " + h));
});
matches(figure).as(
Rectangle.class, (int w, int h) -> System.out.println("square: " + (w * h)),
Circle.class, (int r) -> System.out.println("square: " + (2 * Math.PI * r)),
Else.class, () -> System.out.println("Default square: " + 0)
);
foreach(listRectangles, (int w, int h) -> {
System.out.println("square: " + (w * h));
});
Deconstruct 类 必须有一个或多个提取方法。 它们必须被标记为注解@Extract。参数必须是 输出。由于原始类型和原始类型的包装器不能 通过引用传递我们必须使用包装器,如 IntRef、FloatRef 等。
@Extract
public void deconstruct(IntRef width, IntRef height) {
width.set(this.width);
height.set(this.height);
}