2010-11-18 14 views
1

Je me demande de faire une fonction haskell qui calcule quelque chose commeAjout des pouvoirs des nombres dans haskell avec foldl

1^2 + 2^2 + 3^2 ... 

Bien que je trouve assez facile à mettre en œuvre avec la liste compréhensions

sum [ k^2 | k <- [1..100]] 

ou des cartes

sum (map (\x -> x*x) [1..100]) 

Je rencontre des difficultés à obtenir des plis.

Si je ne me trompe pas, il faut pas moins de 3 paramètres dans une fonction récursive pour obtenir un résultat avec ceci:

  1. La position actuelle (1 ... jusqu'à n)
  2. Le somme actuelle
  3. Où arrêter

Même si je décris cette fonction, il retournera encore un tuple, pas un nombre (comme je l'ai besoin pour!).

Quelqu'un pourrait-il être assez aimable pour me donner des indices sur ce que je pourrais manquer?

Merci

Répondre

5

La "position actuelle" (en fait l'élément suivant dans la liste, tout comme dans les versions de compréhension de la carte et de la liste) et l'endroit où s'arrêter sont implicites dans la liste à replier. La somme actuelle est le paramètre "accumulateur" du pli. Donc, remplissez le vide:

foldl (\runningSum nextNumber -> ____) 0 [1..100] 
+1

Incidemment, je recommanderais aussi généralement' foldl'' (défini dans Data.List) pour cela, ce qui oblige l'accumulateur à être évalué à chaque étape. Lorsque vous compilez avec GHC, il le sait de toute façon, mais dans GHCi ou Hugs, il peut faire la différence entre courir dans un espace constant ou manquer de mémoire. – mokus

6

Si vous regardez la définition de sum, il est juste sum = foldl (+) 0. Donc, si vous remplacez sum par foldl (+) 0 dans l'une de vos solutions, vous avez une solution en utilisant foldl.

Vous pouvez également vous débarrasser du besoin de compréhension de liste ou map en utilisant foldl avec une fonction qui ajoute le carré de son deuxième argument à son premier argument.

Je ne sais pas où vos considérations sur les fonctions récursives figurent dans ce document. Si vous utilisez foldl, vous n'avez pas besoin d'utiliser la récursivité (sauf dans la mesure où foldl est implémenté en utilisant la récursivité). Cependant, vous avez tort qu'une fonction récursive ait besoin de trois arguments: Une fonction récursive additionnant les carrés de chaque élément d'une liste, serait implémentée directement en prenant une liste et en ajoutant la tête de la liste au résultat de l'appel de la fonction sur la queue de la liste. Le cas de base étant squareSum [] = 0. Cela n'a rien à voir avec foldl, cependant.

+0

Bien que l'idée soit bonne, cela ressemble un peu à de la triche. Je ne crois pas que c'est ce que l'enseignant demande :( –

+0

@devoured: Je ne sais pas ce qu'il pourrait demander d'autre (vous devriez probablement vous débarrasser de 'map' et de la compréhension de la liste comme expliqué dans mon deuxième paragraphe) Si l'assignation dit d'utiliser 'foldl', vous n'êtes certainement pas censé utiliser la récursivité explicite – sepp2k