Java 8 和 lambda 演算等价物
Java 8 and lambda calculus equivalent
有人知道如何在 java 中编写(无类型的)lambda 演算的基本表达式吗?即
- 身份 (λx.x),
- 自应用(λx.x x)和
- 函数应用(λx.λarg.x arg)
Java 不是无类型的,所以我想任何解决方案都必须适应类型。
但是我只找到了以下,阅读麻烦,解决办法:
static<T> Function<T,T> identity() {
return x->x;
}
static<T> Function<? extends Function<? super Function,T>,T> self() {
return x->x.apply(x);
}
static <B,C> Function<? extends Function<B,C>, Function<B,C>> apply() {
return x -> arg -> x.apply(arg);
}
而且我什至不确定它们是否正确 (!)。谁能提出更好的选择?
编辑:请注意,我正在尝试应用 lambda 演算的基本概念,尽可能少地使用语法糖或现成的函数。例如。我知道有 identity()、BiFunction 等。我正在尝试仅使用可用的基本 lambda 构造来实现上述内容,这意味着基本上只有函数 application
我用得不多 Java,但它最近包含了 lambda 表达式。实现的基本方法是拥有一个功能接口(只有一个方法的接口)。
lambda 将成为此接口的类型。
interface Apply
{
String ApplyArg(int x);
}
public static void main(String args[])
{
Apply isEven = (n) -> (n%2) == 0;
//output true
System.out.println(isEven.ApplyArg(4));
}
你可以使用泛型类型接口使其更通用。
如果您想将 lambda 作为参数发送(因此是高阶函数),那么您的接口方法将接受另一个接口。
interface Increment {
Int myFunction(Int x);
}
public static Int AnotherFunc(Increment test, Int y){
return test.myFunction(y);
}
public static void main (String args[]) {
Increment inc = (z) -> z++;
AnotherFunc(inc, 1); //output 2
}
您的身份和应用解决方案是正确的。但是,如果不将它们定义为函数,我发现 x->x
和 Function::apply
与 identity()
和 apply()
一样可读,所以我会直接使用它们。
至于自我应用,正如你所注意到的,Java 是类型化的,而且在类型化的 lambda 演算中,自我应用是不可能的(至少在我所知道的所有类型化的 lambda 演算中)。您可以通过使用原始类型(就像您所做的那样)来生成一些东西,但是您实际上丢弃了类型系统的一部分。
而且,你为什么需要这些?
你要找的是这个类型(翻译自table 19 of cardelli's type systems paper)。
interface Untyped {
Untyped call(Untyped x);
}
这种类型完全嵌入了无类型 lambda 演算的项。
static Untyped identity = x -> x;
static Untyped self = x -> x.call(x);
static Untyped apply = f -> x -> f.call(x);
有人知道如何在 java 中编写(无类型的)lambda 演算的基本表达式吗?即
- 身份 (λx.x),
- 自应用(λx.x x)和
- 函数应用(λx.λarg.x arg)
Java 不是无类型的,所以我想任何解决方案都必须适应类型。 但是我只找到了以下,阅读麻烦,解决办法:
static<T> Function<T,T> identity() {
return x->x;
}
static<T> Function<? extends Function<? super Function,T>,T> self() {
return x->x.apply(x);
}
static <B,C> Function<? extends Function<B,C>, Function<B,C>> apply() {
return x -> arg -> x.apply(arg);
}
而且我什至不确定它们是否正确 (!)。谁能提出更好的选择?
编辑:请注意,我正在尝试应用 lambda 演算的基本概念,尽可能少地使用语法糖或现成的函数。例如。我知道有 identity()、BiFunction 等。我正在尝试仅使用可用的基本 lambda 构造来实现上述内容,这意味着基本上只有函数 application
我用得不多 Java,但它最近包含了 lambda 表达式。实现的基本方法是拥有一个功能接口(只有一个方法的接口)。
lambda 将成为此接口的类型。
interface Apply
{
String ApplyArg(int x);
}
public static void main(String args[])
{
Apply isEven = (n) -> (n%2) == 0;
//output true
System.out.println(isEven.ApplyArg(4));
}
你可以使用泛型类型接口使其更通用。
如果您想将 lambda 作为参数发送(因此是高阶函数),那么您的接口方法将接受另一个接口。
interface Increment {
Int myFunction(Int x);
}
public static Int AnotherFunc(Increment test, Int y){
return test.myFunction(y);
}
public static void main (String args[]) {
Increment inc = (z) -> z++;
AnotherFunc(inc, 1); //output 2
}
您的身份和应用解决方案是正确的。但是,如果不将它们定义为函数,我发现 x->x
和 Function::apply
与 identity()
和 apply()
一样可读,所以我会直接使用它们。
至于自我应用,正如你所注意到的,Java 是类型化的,而且在类型化的 lambda 演算中,自我应用是不可能的(至少在我所知道的所有类型化的 lambda 演算中)。您可以通过使用原始类型(就像您所做的那样)来生成一些东西,但是您实际上丢弃了类型系统的一部分。
而且,你为什么需要这些?
你要找的是这个类型(翻译自table 19 of cardelli's type systems paper)。
interface Untyped {
Untyped call(Untyped x);
}
这种类型完全嵌入了无类型 lambda 演算的项。
static Untyped identity = x -> x;
static Untyped self = x -> x.call(x);
static Untyped apply = f -> x -> f.call(x);