web-dev-qa-db-fra.com

Java 8 et équivalent lambda calcul

Est-ce que quelqu'un a une idée sur la façon d'écrire les expressions de base du calcul lambda (non typé) en java? c'est à dire. 

  • identité (λx.x), 
  • auto-application (λx.x x) et 
  • application de fonction (λx.λarg.x arg)

Java n'est pas non typé, donc je suppose que toute solution devra s'adapter aux types. Mais je n'ai trouvé que les solutions suivantes:

static<T> Function<T,T> identity() {
    return x->x;
}

static<T> Function<? extends Function<? super Function,T>,T> self() {
    return x->x.apply(x);
}

static <B,C> Function<? extends Function<B,C>, Function<B,C>> apply() {
   return x -> arg -> x.apply(arg);
}

et je ne suis même pas sûr qu'ils sont corrects (!). Quelqu'un peut-il proposer une meilleure alternative?


Edit: Notez que j'essaie d'appliquer les notions de base du calcul lambda avec le moins possible de sucre syntaxique ou de fonctions prédéfinies. Par exemple. Je sais qu'il y a identity (), BiFunction, etc. J'essaie de mettre en œuvre ce qui précède avec uniquement les constructions lambda de base disponibles, ce qui signifie fondamentalement uniquement l'application de fonction

8
user2465039

Vos solutions d'identité et d'application sont correctes. Cependant, si je ne les définissais pas comme des fonctions, je trouve x->x et Function::apply aussi lisibles que identity() et apply(), je les utiliserais donc directement.

Pour ce qui est de l'auto-application, eh bien, comme vous le constatez, Java est dactylographié, et aussi dans le lambda calcul typé, l'auto-application est impossible (du moins dans tous les lambda calculés que je connais). Vous pouvez produire quelque chose en utilisant des types bruts (comme vous l'avez fait), mais vous perdez essentiellement la partie du système de types. 

Mais aussi, pourquoi avez-vous besoin de tout cela?

6
Hoopje

Je n'utilise pas beaucoup Java, mais il a récemment inclus les expressions lambda. La méthode de base pour implémenter est d'avoir une interface fonctionnelle (interface n'ayant qu'une seule méthode). 

Le lambda sera alors un type de cette interface.

    interface Apply
    {
          String ApplyArg(int x);
    }

    public static void main(String args[])
    {
       Apply isEven = (n) -> (n%2) == 0;
       //output true
       System.out.println(isEven.ApplyArg(4));
    }

Vous pouvez utiliser une interface de type générique pour la rendre plus universelle.

Si vous voulez envoyer lambda sous forme d'arguments (donc de fonctions d'ordre supérieur), votre méthode d'interface acceptera une autre interface.

interface Increment {
    Int myFunction(Int x);
}

public static Int AnotherFunc(Increment test, Int y){
  return test.myFunction(y);
}

public static void main (String args[]) {

   Increment inc = (z) -> z++;
   AnotherFunc(inc, 1); //output 2

}
0
peeyush singh