Sto lavorando su una piccola libreria funzionale scritta in Java, che riproduce lo stile funzionale della programmazione. Sono bloccato con un cast di tipo indesiderato in una delle mie definizioni di metodo e mi piacerebbe un po 'd'aiuto.
Ok, quindi non abbiamo funzioni di prima classe in Java, quindi li definisco come oggetti, con un metodo 'apply ()' come questo:
public abstract class Function2<R,T1,T2> {
public abstract R apply(final T1 paramOne, final T2 paramTwo);
}
Quindi definisco il mio metodo contro come oggetto Function2, che posso passare in giro come se fosse una funzione in un'altra lingua che lo supporta:
public static <T> Function2<List<T>, T, List<T>> cons(){
return new Function2<List<T>, T, List<T>>(){
@Override
public List<T> apply(T x, List<T> xs) {
return new NonEmptyList<T>(x, xs);
}
};
}
Ho omesso la mia struttura di lista per brevità; Supponiamo che sia una struttura di dati di lista funzionale di stile con tutto il solito head / tail / etc. operazioni.
Quindi voglio implementare una funzione come "reverse", che restituisce un elenco di elementi in ordine inverso. Io uso foldl1 (piega una lista non vuota da sinistra) per ottenere questo e passa la funzione cons come parametro a fold1 in questo modo:
public static <T> List<T> foldl( Function2<List<T>, T, List<T>> f,
List<T> acc,
List<T> xs ){
if(xs.isEmpty()){ return acc; }
return foldl(f, (f.apply(xs.head(), acc)), xs.tail());
}
public static <T> List<T> reverse(List<T> xs){
// how do I avoid this cast??
return foldl( (Function2) cons(), new EmptyList(), xs);
}
Ma quando passo il mio oggetto "cons ()" in "reverse", ho bisogno di lanciarlo come una Funzione2, e non ho idea di come evitare di farlo. Ho provato tutti i tipi di problemi con i tipi ... Sento che questa è semplicemente una mancanza di esperienza da parte mia con il sistema di tipo Java ... chiunque?
PS. Sono a conoscenza di altre librerie funzionali in Java, volevo solo fare la mia piccola esperienza di apprendimento.
EDIT - OK, quindi ora sto usando un normale "foldl" per recuperare un elenco, ma devo ancora eseguire il cast? Il tipo di ritorno di "contro" è allineato a "foldl" ...