2010-05-01 7 views
1

Aidez-moi à écrire une fonction qui prend deux arguments: une liste d'ints et un index (int) et renvoie une liste d'entiers avec des valeurs négatives sur la position d'index spécifiée dans la table.Fonction récursive haskell

La fonction aurait cette signature MyReverse :: [Int]->Int->[Int].

Par exemple: myReverse [1,2,3,4,5] 3 = [1,2,-3,4,5].

Si l'index est supérieur à la longueur de la liste ou inférieur à 0, renvoie la même liste.

+6

Cela sent comme les devoirs. Si oui, identifiez-le comme tel. –

+0

'itemInverse' (ou' inverseItem') serait un meilleur nom, car "reverse" implique une opération entièrement différente sur les listes. – outis

+0

ou 'negateItem'. Inverse peut signifier 1/x. – kennytm

Répondre

4
myReverse :: [Int] -> Int -> [Int] 
myReverse [] n = [] 
myReverse (x:xs) n 
| n < 0  = x:xs 
| n == 0 = (-x):xs 
| otherwise = x:(myReverse xs (n-1)) 

Cela indexe le tableau de 0; votre exemple indexe de 1, mais n'est pas défini pour le cas n == 0. Le correctif pour prendre à l'index de 1 devrait être assez évident :)

De plus, votre capitalisation est incohérente; MyReverse est différent de myReverse, et seul ce dernier est valide en tant que fonction.

Résultats, à GHCi:

*Main> myReverse [10,20,30,40,50] 0 
[-10,20,30,40,50] 
*Main> myReverse [10,20,30,40,50] 2 
[10,20,-30,40,50] 
*Main> myReverse [10,20,30,40,50] 3 
[10,20,30,-40,50] 
*Main> myReverse [10,20,30,40,50] 5 
[10,20,30,40,50] 
*Main> myReverse [10,20,30,40,50] (-1) 
[10,20,30,40,50] 

version plus générique qui fait la même chose, en utilisant une définition inutile pour myReverse:

myGeneric :: (a -> a) -> [a] -> Int -> [a] 
myGeneric f [] n = [] 
myGeneric f (x:xs) n 
| n < 0  = x:xs 
| n == 0 = (f x):xs 
| otherwise = x:(myGeneric f xs (n-1)) 

myReverse :: [Int] -> Int -> [Int] 
myReverse = myGeneric negate 
+0

merci, ma solution n'a pas fonctionné à cause du manque d'accolades ob (-x): xs merci pour l'aide – gruber

+0

@snorlaks: Si vous avez une solution partielle, les gens apprécieront toujours que vous postez avec la question, et dire ce que vous 'ai essayé, où vous pensez que le problème est, etc –

-1
myReverse xs i = 
    let j = i - 1 
    in take j xs 
    ++ - (xs !! j) 
     : drop i xs 
+0

Ceci est très non-idiomatique Haskell, et très inefficace. – MtnViewMark

+0

Ohhh c'est ttricku, mais intéressant, pourriez-vous s'il vous plaît expliquer cet exemple pour moi étape par étape? merci pour l'aide – gruber

+0

Soit j = i -1 vous donne l'index à l'élément juste avant celui qui doit être changé. prendre j xs vous donne une liste d'éléments avant que je "++" est concaténation liste "!!" est l'index ":" met la valeur négative sur la tête de drop i xs drop i xs est la liste xs avec les premiers éléments i supprimés. Donc, il divise la liste dans la partie avant la partie niée et tout ce que je après, puis il colle tout de nouveau ensemble – stonemetal