63 votes

Comment créez-vous une fonction qui retourne une fonction dans la langue de votre choix?

Récemment, j'ai été l'apprentissage de Lua et j'aime la façon dont il est facile d'écrire une fonction qui retourne une fonction. Je sais que c'est assez facile en Perl, mais je ne pense pas que je peux le faire en C sans quelque chagrin d'amour. Comment écrivez-vous un générateur de fonction dans votre langue préférée?


De sorte qu'il est plus facile de comparer une langue à l'autre, s'il vous plaît écrire une fonction qui génère une formule quadratique:

f(x) = ax^2 + bx + c

Votre fonction doit prendre trois valeurs (a, b, et c) et les retours f. Pour tester la fonction, montrer comment générer de la formule quadratique:

f(x) = x^2 - 79x + 1601

De montrer ensuite comment calculer le f(42). Je vais poster mon Lua résultat comme une réponse pour un exemple.


Quelques exigences supplémentaires qui en est ressorti:

  1. Tout d' a, b, c, x, et f(x) doivent être des nombres à virgule flottante.

  2. Le générateur de fonction doit être réentrant. Cela signifie qu'il devrait être possible de générer:

    g(x) = x^2 + x + 41
    

    Et puis utiliser les deux f(x) et g(x) dans le même champ d'application.

La plupart des réponses sont déjà conformes à ces exigences. Si vous voyez une réponse qui n'a pas, n'hésitez pas à corriger ou remarque le problème dans un commentaire.

50voto

Martin Points 3187

JavaScript

 function quadratic(a, b, c) 
{
    return function(x) 
    {
        return a*(x*x) + b*x +c;
    }
}

var f = quadratic(1, -79, 1601);
alert(f(42));
 

44voto

Khoth Points 7001

Haskell

quadratic a b c = \x -> a*x*x + b*x + c

ou, je pense que plus joliment:

quadratic a b c x = a*x*x + b*x + c

(si vous l'appelez, avec seulement trois paramètres, vous obtenez de retour d'une fonction prêt pour le quatrième)

Pour l'utiliser:

let f = quadratic 1 -79 1601 in f 42

Modifier

La généralisation à l'arbitraire-ordre des polynômes (comme OCaml réponse ne) est encore plus beau en Haskell:

polynomial coeff = sum . zipWith (*) coeff . flip iterate 1 . (*)
f = polynomial [1601, -79, 1]
main = print $ f 42

Pervers

Le traitement des fonctions comme s'ils étaient des nombres:

{-# LANGUAGE FlexibleInstances #-}
instance Eq (a -> a) where (==) = const . const False
instance Show (a -> a) where show = const "->"
instance (Num a) => Num (a -> a) where
    (f + g) x = f x + g x; (f * g) x = f x * g x
    negate f = negate . f; abs f = abs . f; signum f = signum . f
    fromInteger = const . fromInteger
instance (Fractional a) => Fractional (a -> a) where
    (f / g) x = f x / g x
    fromRational = const . fromRational

quadratic a b c = a*x^2 + b*x + c
    where x = id :: (Fractional t) => t -> t
f = quadratic 1 (-79) 1601
main = print $ f 42

...même si 1 (-79) 1601 n'étaient pas constantes numériques, ce serait d'une application supplémentaire de la const.

31voto

zweiterlinde Points 5984

Python

 def quadratic(a, b, c):
    return lambda x: a*x**2 + b*x + c

print quadratic(1, -79, 1601)(42) 
# Outputs 47
 


Sans utiliser lambda (les fonctions peuvent être transmises en Python comme n'importe quelle variable, classe, etc.):

 def quadratic(a, b, c):
    def returned_function(x):
        return a*x**2 + b*x + c
    return returned_function
print quadratic(1, -79, 1601)(42)
# Outputs 47
 


Équivalent en utilisant une classe plutôt que de retourner une fonction:

 class quadratic:
    def __init__(self, a, b, c):
        self.a, self.b, self.c = a, b, c
    def __call__(self, x):
        return self.a*x**2 + self.b*x + self.c

print quadratic(1, -79, 1601)(42)
# Outputs 47
 

27voto

Patrick Points 20392

C # utilisant uniquement Lambdas

 Func<double, double, double, Func<double, double>> curry = 
    (a, b, c) => (x) => (a * (x * x) + b * x + c);
Func<double, double> quad = curry(1, -79, 1601);
 

25voto

Ionuț G. Stan Points 62482

PHP 5.3

 function quadratic($a, $b, $c) 
{
    return function($x) use($a, $b, $c)
    {
        return $a*($x*$x) + $b*$x + $c;
    };
}

$f = quadratic(1, -79, 1601);
echo $f(42);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X