web-dev-qa-db-fra.com

Une solution pure-fonctionnelle peut-elle être aussi propre que l'impératif?

J'ai un exercice sur Python comme suit:

  • un polynôme est donné comme un tuple de coefficients de sorte que les pouvoirs soient déterminés par les index, par exemple: (9,7,5) signifie 9 + 7 * x + 5 * x ^ 2

  • écrivez une fonction pour calculer sa valeur pour X

Depuis que je suis dans la programmation fonctionnelle ces derniers temps, j'ai écrit

def evaluate1(poly, x):
  coeff = 0
  power = 1
  return reduce(lambda accu,pair : accu + pair[coeff] * x**pair[power],
                map(lambda x,y:(x,y), poly, range(len(poly))),
                0)

ce que je considère illisible, alors j'ai écrit

def evaluate2(poly, x):
  power = 0
  result = 1
  return reduce(lambda accu,coeff : (accu[power]+1, accu[result] + coeff * x**accu[power]),
                poly,
                (0,0)
               )[result]

qui est au moins comme illisible, alors j'ai écrit

def evaluate3(poly, x):
  return poly[0]+x*evaluate(poly[1:],x) if len(poly)>0 else 0

qui pourrait être moins efficace (éditer: j'avais tort!) Puisqu'il utilise de nombreuses multiplications au lieu de l'exponentiation, je ne me soucie en principe pas des mesures ici (modifier: comment idiot de moi! Mesure aurait signalé ma mauvaise idée!) Et toujours pas aussi lisible (sans doute) que la solution itérative:

def evaluate4(poly, x):
  result = 0
  for i in range(0,len(poly)):
      result += poly[i] * x**i
  return result

Existe-t-il une solution pure-fonctionnelle aussi lisible que l'impératif et la proximité d'une efficacité?

Certes, un changement de représentation aiderait, mais cela a été donné par l'exercice.

Peut être haskell ou lisp aswell, pas seulement python.

10
user1358

Si vous juste Avoir un tuple (fixe), pourquoi ne pas faire cela (à Haskell):

evalPolyTuple (c, b, a) x = c + b*x + a*x^2

Si vous avez plutôt une liste de coefficients, vous pouvez utiliser:

evalPolyList coefs x = sum $ zipWith (\c p -> c*x^p) coefs [0..]

ou avec un réduit comme vous l'aviez:

evalPolyList' coefs x = foldl' (\sum (c, p) -> sum + c*x^p) 0 $ Zip coefs [0..]
4
paul