gpt4 book ai didi

java - 让Java函数对象封装泛型函数的正确方法

转载 作者:行者123 更新时间:2023-12-04 05:27:06 24 4
gpt4 key购买 nike

这是一个对 Haskell 和 C++ 模板元编程做过多的人提出的一个复杂但有趣的问题。请多多包涵

我正在编写一些通用 Java 代码来检查函数的某些代数属性,并且我在为其中一些提出适当的类型时遇到了一些困难。

作为一个有效的例子,这是一个检查函数是否可交换的函数:

<E, R>
boolean checkCommutative( Binary<E,E,R> f
, Binary<R,R,Boolean> eq
, E a, E b)
{
return eq.ap(f.ap(a,b), f.ap(b, a));
}

此函数应为:“二进制函数 f 接受两个 E 并产生 R 是可交换的(由比较两个 eq 的函数 R 定义相等),如果任何 ab 类型的 Ef 应用于 (a,b) 等于 f 应用于 (b,a) 。”

然后我可以测试给定函数 C.plus(Integer,Integer)通过执行以下操作是可交换的:
class Plus implements Binary<Integer, Integer, Integer> {
Integer ap(Integer a, Integer b) { return C.plus(a,b); }
}

class Eq implements Binary<Integer, Integer, Boolean> {
Boolean ap(Integer a, Integer b) { return a.equals(b); }
}

checkCommutative(new Plus(), new Eq(), rand(), rand());

一切都很好。

现在我想实现一些更复杂的东西。假设我有一个通用接口(interface) Group<E>使用加号方法:
interface Group<E> {
E plus(E,E);
}

假设我有两个实现: TheIntegersTheRationals :
class TheIntegers  implements Group<Integer> { ... }
class TheRationals implements Group<Fraction> { ... }

现在,我希望能够理解泛型函数 F从整数到有理数通过函数 g 进行通勤就像 Group.plus .作为第一个剪辑,我想写这样的东西:
<E, R>
booleanCheckCommutesWith( Unary<E,R> f
, ?? g
, Binary<R,R,Boolean> eq
, E a, E b)
{
return eq.ap(f.ap(g.ap(a,b)), g.ap(f.ap(a), f.ap(b));
}

class F implements Unary<TheIntegers, TheRationals> {
Fraction ap (Integer x) { ... }
}

checkCommutesWith(new F(), new Plus(), new Eq(), rand(), rand());

这里的问题是 g 的类型应该是什么?是?问题是 g应用于两种不同的类型: ER .在具体的例子中,我们想要 g代表 Group<Integer>.plus(Integer,Integer)Group<Fraction>.plus(Fraction,Fraction) .

现在,执行 checkCommutesWith以上不可能工作,因为对 g.ap 的两次调用之间的唯一区别是是泛型类型,已被删除。因此,我将通过将域和范围添加为对象来对其进行一些修改:
boolean checkCommutesWith( Unary<DE,RE> f
, ?? g
, Binary<RE,RE,Boolean> eq
, S domain, S range
, E x, E y)
{
return eq.ap( f.ap(g.ap(domain, x, y)),
, g.ap(range, f.ap(x), f.ap(y))
);
}

class Plus implements ??
{
<E, G extends Group<E>>
E ap (G gp, E x, E y) { return gp.plus(x,y); }
}

那么界面( ?? )应该是什么样子?如果这是 C++,我会写相当于
interface ?? <T> {
<E, S extends T<E>>
E ap(S, E, E);
}

但 AFAICT Java 没有模板模板参数的等效项。这就是我卡住的地方。

请注意,我不想将 Group 作为 checkCommutesWith 签名的一部分。 ,因为我也希望能够将此代码与其他结构一起使用。我认为应该可以有一个通用的定义(对于“应该”的一些定义:))。

更新/澄清 这里问题的症结在于集合之间映射的定义属性是它们与 eq() 通勤。群同态的定义属性是它们与 plus() 交换。环同态的定义属性是它们与 times() 通勤。我正在尝试定义一个通用的 commutesWith 函数来捕捉这个想法,并且我正在寻找正确的抽象来封装 eq、plus 和 times(以及其他结构)。

最佳答案

我不确定它是否足以满足您的目的,但您可以检查 JScience 中定义的类型结构。图书馆。尤其是 org.jscience.mathematics.structure 中指定的接口(interface)。可能代表一个有用的起点。

关于java - 让Java函数对象封装泛型函数的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13080042/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com