2013-05-27 54 views
7

我已经做了一些编程和Haskell,并希望在Groovy中实现一些Haskell列表处理函数。以下是unfoldr的实现。基本上A是生成的迭代器的类型(即列表),B是状态。在Groovy中输入元组和闭包

有两件事情我想给强类型:

  1. 我希望能说Tuple<A,B>,而不是仅仅Tuple
  2. 我希望能够定义闭包的参数,而不仅仅是结果类型。

生成枚举从1到100的迭代器的示例代码如下,并链接在ideone here上。

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"; 
} 
+0

你可以声明闭包参数的类型并使用'CompileStatic',这就是你想要的吗?或者你想声明'private Closure f'参数类型?像'私人关闭 f'? – Will

+0

难道你不想在这方面做点什么吗? – Will

+0

你好。对不起,我现在已经转换为使用数组,而不是元组。但是,是的,'私人关闭,C> f'是我真正想要的。 – Clinton

回答

2

你面对的问题在这里基本上是Java泛型,它无法声明一个容器类型的变量列表。诚然,对于静态编译来说,Tuple特别不好,因为它甚至不包含泛型的最小值,但是你必须考虑Tuple基本上是一个包含任意数量元素的列表。你可以得到的最大值是Tuple,其中T是所有元素的基类。如果你确定,那么我建议使用任何列表。将Tuple定义为具有两个元素的元组,其中第一个具有类型A,第二个类型为B,然后定义Tuple,其中第三个元素具有类型C,但在Java中是不可能的。相反,你需要真正的不同类型,如Tuple2和Tuple3来TupleN。我正在非常详细地解释这一点,因为这与为什么在闭合上没有这种信息基本相同。可以使用闭包来使用从0到N的任意数量的参数进行调用。但泛型没有办法声明这一点。

在Groovy 2.2,你将能够reaplace截流Unfoldr有适合您的需要任何接口,而无需高清改变使用U = unfoldr({X - >如果(X < 100){新的元组(X + 1,x + 1)} else null;},0);