Cli*_*ton 7 groovy haskell types strong-typing
我已经完成了一些编程和Haskell,并希望在Groovy中实现一些Haskell列表处理函数.下面是一个实现unfoldr
.基本上A
是生成的迭代器(即列表)的类型,并且B
是状态.
有两件事我想给更强的类型:
Tuple<A,B>
而不仅仅是Tuple
其产生枚举从1至100的迭代实施例的代码是下面和上ideone链接这里.
class Unfoldr<A,B> implements java.util.Iterator<A>
{
public Unfoldr(Closure<Tuple> f, B init)
{
this.f = f;
this.state = f(init);
}
public synchronized A next()
{
if (hasNext())
{
A curr = state.get(0);
state = f(state.get(1));
return curr;
}
else
{
throw java.lang.NoSuchElementException;
}
}
public synchronized boolean hasNext()
{
return (state != null);
}
public void remove() { throw UnsupportedOperationException; }
private Closure<Tuple> f;
private Tuple state;
}
def unfoldr = { f, init -> new Unfoldr(f, init) };
def u = unfoldr({ x -> if (x < 100) { new Tuple(x + 1, x + 1) } else null; }, 0);
for(e in u)
{
print e;
print "\n";
}
Run Code Online (Sandbox Code Playgroud)
您面临的问题基本上是 Java 泛型及其无法为容器声明类型的变量列表。确实,元组对于静态编译尤其不利,因为它甚至不包含最少的泛型,但您必须考虑元组基本上是一个具有任意数量元素的列表。您可以获得的最大值是 Tuple,其中 T 是所有元素的基类。如果您对此表示同意,那么我建议您使用任何列表。在 Java 中,将 Tuple 定义为具有两个元素的元组,其中第一个元素具有类型 A,第二个元素具有类型 B,然后定义第三个元素具有类型 C 的 Tuple。相反,您将需要真正不同的类型,例如 Tuple2 和 Tuple3 到 TupleN。我之所以如此详细地解释这一点,是因为这基本上与为什么没有关于 Closure 的此类信息的原因相同。闭包可用于使用从 0 到 N 的任意数量的参数进行调用。但是在泛型中无法声明这一点。
在 Groovy 2.2 中,您将能够用任何适合您需求的接口替换 Unfoldr 中的 Closure,而无需更改用法 def u = Expandr({ x -> if (x < 100) { new Tuple(x + 1, x + 1) } 否则为空; }, 0);