2013-05-27 63 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);