2010-12-02 18 views
2

Disons que j'ai une liste de valeurs à laquelle je veux appliquer une séquence d'opérations jusqu'à ce que je reçois un résultat final:Comment exécuter une séquence d'opérations (fonctions) dans Haskell?

[0, 1, 2] 

firstOperation xs = map (+1) xs 
secondOperation xs = filter even xs 
thirdOperation xs = sum xs 

Même si je suis sûr qu'il ya d'autres meilleures façons de gérer cela, le seul Je sais actuellement est de définir une fonction qui appelle toutes ces fonctions imbriquées les unes dans les autres:

runAllOperations xs = thirdOperation (secondOperation (firstOperation xs)) 

mais cela est à la fois laid et pose le problème que si j'ai 10 opérations, transforme ce bit de code dans un cauchemar maintanance .

Quelle est la bonne façon d'implémenter quelque chose du genre ici? Gardez à l'esprit l'exemple que j'ai donné ci-dessus est juste une simplification excessive de ce que je fais face à mon projet actuel.

+0

Quand je regarde vos extraits de code que je vois que les transformations que vous souhaitez appliquer à une entrée. Où sont les opérations? Astuce: Je pense que vous pensez à Haskell dans le mauvais sens et vous posez donc la mauvaise question sans le savoir. –

+0

Je crois aussi que c'est le cas. Malheureusement :( –

Répondre

3

Si vous pouvez faire une liste de toutes les opérations, vous pouvez plier l'opérateur de composition sur cette liste:

foldr (.) id fns 

Vous pouvez ensuite appliquer le résultat de cela aux valeurs initiales. Il se peut que vous deviez appliquer séparément une étape de réduction finale.

+0

Seulement si toutes les opérations ont le même type (c'est-à-dire '[a] -> [a]', rien comme '[a] -> [b]'). – ephemient

+0

Mais que faire si je veux quelque chose comme [a] -> [b] -> [c] (comme dans l'exemple ci-dessus, où le résultat final est un scalaire)? –

+0

@ ephemient: Yup, vous allez avoir du mal à les obtenir tous dans une liste sinon. –

6

. ou $ sont de façon plus lisible que ( et )

runAllOperations xs = thirdOperation $ secondOperation $ firstOperation xs 

ou

runAllOperations = thirdOperation . secondOperation . firstOperation 
+0

+1 pour (.), Mais je ne pense pas que $ soit toujours meilleur que (et). – Martijn