2017-10-21 23 views
1

J'essaie d'utiliser des fonctions de récursion et d'ordre supérieur pour faire quelque chose au premier élément d'une liste, puis à tous les autres éléments de la liste, par exemple ajouter 3 au 1er , 3ème, 5ème .. etc.Erreur de modèle non exhaustive dans la fonction récursive

Le problème que je rencontre est qu'il me donne l'erreur non-exhaustive pattern. Toute aide serait appréciée. Voici ce que j'ai jusqu'à présent:

applyToEveryOther :: (a -> b) -> [a] -> [b] 
applyToEveryOther _ [] = [] 
applyToEveryOther f (x:y:xs) = f x : applyToEveryOther f xs 

et ceux-ci sont quelques lignes supplémentaires que je l'ai essayé, mais ne contribuent pas à:

applyToEveryOther _ [x] = f x 
applyToEveryOther f [x] = f x 
+1

Copie possible de [Haskell: Double tous les 2 éléments dans la liste] (https://stackoverflow.com/questions/17383169/haskell-double-every-2nd-element-in-list) – cdk

Répondre

4

Le cas d'un seul élément devrait aussi retourner une liste (de type [b]):

applyToEveryOther f [x] = [f x] 
+0

Merci, ça a marché! –

+0

Si j'ai une autre question à ce sujet .. si je voulais garder la liste entière, pas seulement garder ceux qui ont été transformés, comment pourrais-je faire cela. Je suis nouveau à cela et ne savais pas si je fais un nouveau poste ou non –

+0

@loutej certainement un nouveau poste! (Je pense que la réponse est 'f x: y: applyToEveryOther f xs' mais elle sera mieux mise en forme et plus utile aux autres en tant que nouveau message). –

1

Une autre solution qui n'utilise pas récursion explicite, mais seulement des fonctions d'ordre supérieur:

import Data.List (cycle) 

applyToEveryOther f = zipWith ($) (cycle [f, id]) 

cycle crée une liste infinie de fonctions en alternance f, id, f, id, etc.

zipWith ($) applique les fonctions dans la liste des éléments correspondants de votre liste d'entrée.

[(+1), id, (+1), id, (+1), id, (+1), id, ...] 
[ 1, 2, 3, 4, 5, 6, 7, 8  ] 
============================================= 
[ 2, 2, 4, 4, 6, 6, 8, 8  ] 

(Pointe du chapeau: le problème de l'application d'une liste des fonctions par morceaux à une liste d'arguments, avec une solution à l'aide zipWith ($), appeared recently sur le flux Twitter 1HaskellADay.)

(ma propre solution inférieure a été d'utiliser le constructeur de type ZipList trouvé dans Control.Applicative, appliqué ici, il ressemblerait à quelque chose comme

import Control.Applicative 

applyToEveryOther f xs = let fs = cycle [f,id] 
          in getZipList (ZipList fs <*> ZipList xs) 

)