2013-05-27 23 views
7

私は少しのプログラミングとHaskellを行い、GroovyでいくつかのHaskellリスト処理関数を実装したかったのです。以下はunfoldrの実装です。基本的にAは、結果のイテレータ(つまりリスト)のタイプであり、Bは状態です。Groovyの型付きタプルとクロージャ

私は強いタイプを与えたいのですが二つあります。

  1. は私が定義できるようにしたいと思いちょうどTuple
  2. 私はTuple<A,B>の代わりを言うことできるようにしたいのですが結果の型だけでなく、クロージャの引数

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'引数型を宣言したいでしょうか? 'Private Closure f'のように? – Will

+0

あなたはこれについていくつかの光を当てるのが好きではないですか? – Will

+0

こんにちは。申し訳ありませんが、私はタプルではなく配列を使って変換しました。しかし、はい、 'Private Closure 、C> f'が私が本当に探していたものでした。 – Clinton

答えて

2

ここで問題になるのは、基本的にはJavaジェネリックであり、コンテナのタイプの可変リストを宣言できないことです。確かに、タプルは静的コンパイルには特に悪いですが、それは最小限のジェネリックも含まれていないためですが、タプルは基本的に任意の量の要素を持つリストであると考える必要があります。取得できる最大値はTupleです.Tはすべての要素の基本クラスです。それで大丈夫なら、代わりにリストを使うことをお勧めします。 Tupleを2つの要素を持つタプルとして定義します。最初の要素は型A、2番目の要素は型Bで、3番目の要素がC型のTupleを定義します。Javaではできません。代わりに、Tuple2とTuple3のような本当の異なるタイプが必要です。私はこれを非常に詳細に説明しています。なぜなら、これは基本的にClosureに関する情報がない理由と同じ理由です。クロージャは、0からNの任意の数の引数を使用して呼び出しを行うために使用できます。しかし、これを宣言するためのジェネリックスの方法はありません。

Groovy 2.2では、使用を変更することなく、Unfoldrの任意のインタフェースでClosureを置き換えることができます。def u = unfoldr({x - > if(x < 100){new Tuple + 1、x + 1)} else else;}、0);

関連する問題