2013-05-27 6 views
7

Ho eseguito un po 'di programmazione e Haskell e ho voluto implementare alcune funzioni di elaborazione dell'elenco Haskell in Groovy. Di seguito è una implementazione di unfoldr. Fondamentalmente lo A è il tipo dell'iteratore risultante (ad esempio, l'elenco) e lo stato è B.Tuple e chiusure tipizzate in Groovy

Ci sono due cose che mi piacerebbe dare tipi più forti per:

  1. mi piacerebbe poter dire Tuple<A,B> invece di Tuple
  2. mi piacerebbe essere in grado di definire gli argomenti della chiusura, non solo il tipo di risultato.

Esempio di codice che genera un iteratore che enumera da 1 a 100 è sotto e collegato su 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

Puoi dichiarare il tipo degli argomenti della chiusura e usare 'CompileStatic', è quello che vuoi? O vuoi dichiarare il tipo di argomento 'Closure privato ? Come "chiusura privata f'? – Will

+0

non ti piacerebbe far luce su questo? – Will

+0

Ciao Will. Scusa, ora mi sono convertito all'utilizzo di matrici, non di tuple. Ma sì, 'Closure privato , C> f' era quello che stavo davvero cercando. – Clinton

risposta

2

Il problema che dovete affrontare è qui fondamentalmente generici Java e la sua incapacità di dichiarare un elenco di variabili di tipi per un contenitore. È vero, Tuple è particolarmente negativo per la compilazione statica, poiché non contiene nemmeno il minimo di generici, ma devi considerare che Tuple è fondamentalmente una lista con una quantità arbitraria di elementi. Il massimo che puoi ottenere è Tupla, dove T è la classe base per tutti gli elementi. E se sei d'accordo, allora ti suggerisco di usare qualsiasi lista. Definire la tupla come una tupla con due elementi in cui il primo ha tipo A e il secondo il tipo B e che poi definirà Tuple in cui il terzo elemento ha il tipo C non è possibile in Java. Invece occorreranno tipi diversi reali come Tuple2 e Tuple3 in TupleN. Lo sto spiegando in modo così dettagliato, perché questo è fondamentalmente lo stesso motivo per cui non ci sono tali informazioni su Closure. La chiusura può essere utilizzata per effettuare chiamate utilizzando un numero qualsiasi di argomenti da 0 a N. Ma non c'è modo in generici di dichiararlo.

In Groovy 2.2 si sarà in grado di reaplace Chiusura in Unfoldr con qualsiasi interfaccia che si adatta alle vostre esigenze, senza dover modificare l'utilizzo DEF u = unfoldr ({x -> se (x < 100) {nuova tupla (x + 1, x + 1)} else null;}, 0);