2010-10-28 6 views
8

suivant fonctionne évidemment, mais je n'aime pas emballer des articles dans Tuple,arguments de la fonction Goyave

ImmutableMap<String, Function<Tuple2<Double>, Double>> op = new // 
    ImmutableMap.Builder<String, Function<Tuple2<Double>, Double>>() 
      .put("+", new Function<Tuple2<Double>, Double>() { 
       @Override public Double apply(Tuple2<Double> data) { 
        return data.Val_1 + data.Val_2; 
       } 
      }).build(); 
    System.out.println(op.get("+").apply(new Tuple2<Double>(3d, 4d))); 

Je veux écrire quelque chose comme:

ImmutableMap<String, Function<Double[], Double>> op = new // 
    ImmutableMap.Builder<String, Function<Double[], Double>>() 
      .put("+", new Function<Double[], Double>() { 
       @Override 
       public Double apply(Double... data) { 
        return data[0] + data[1]; 
       } 
      }).build(); 
    System.out.println(op.get("+").apply(3d, 4d)); 

aide serait plus utile, ty.

Edit: Problème résolu, a commencé à utiliser:

public interface T2Function<T> { 
    T apply(T Val_1, T Val_2); 
} 
+0

Vous pouvez le faire en retournant un autre 'Function' de votre' Function.apply', puis en appliquant cela au second argument. 'Function.apply (a) .apply (b)'. La fonction "interne" utiliserait directement 'a' et recevrait' b' comme paramètre. Cela pourrait être étendu pour les paramètres 'n'. Cela imiterait le traitement des fonctions de Haskell, mais je ne suis pas sûr de ce que vous en retireriez à Javaland. – jpaugh

Répondre

14

Je pense que vous seriez mieux à l'aide d'une interface de votre propre, quelque chose comme ceci:

public interface Operation { 
    double apply(double a, double b); 
} 

Function de Goyave est une seule fonction d'argument et pas vraiment approprié pour n'importe quoi multi-argument.

Une autre chose que j'ai expérimentée est un ReduceFunction<F, T> qui s'avère être utilisable pour une telle chose. Il est destiné à être utilisé avec l'opération reduce ou fold et ressemble à quelque chose comme:

public interface ReduceFunction<F, T> { 
    T apply(T a, F b); // I can't decide on good names for the parameters =(
} 

Cela vous permet de faire des choses comme

List<Double> doubles = ... 
Double sum = reduce(doubles, MathOps.add(), 0.0); 

MathOps.add() est un ReduceFunction<Double, Double> qui fait la chose évidente.

+0

@CollinD: Qu'est-ce que réduire et plier? Je ne comprends pas. – Emil

+4

@Emil: Ce sont des constructions de programmation fonctionnelles, appelées fonctions d'ordre supérieur. Un «réduire» réduira généralement une liste en une seule valeur en combinant des éléments à travers une fonction fournie. Un «pli» est similaire à une opération de réduction, sauf qu'il peut être ensemencé avec une valeur initiale. La fonction fournie au «fold» combinera alors les éléments de liste et la valeur ensemencée. – gpampara

+0

@gpampara: Cette programmation fonctionnelle est-elle effectuée à l'aide d'une API? – Emil

3

On dirait que vous recherchez un équivalent à C# Func: Spécialisé dans votre cas avec les arguments et la valeur de retour du même type.

Il y a deux autres questions avec de bonnes réponses au sujet de cette ..

Comme d'autres réponses laissent entrevoir, vous pouvez être coincé au milieu entre deux paradigmes ici (OO et fonctionnel), quelque chose avec lequel la conception de la langue est discutablement rattraper plus vite que la bonne pratique est. Si vous voulez continuer dans cette eau trouble, vous pouvez essayer functionaljava.

Voir Mixing object-oriented and functional programming pour une discussion plus intéressante.

Questions connexes