2010-05-01 3 views
1

Пожалуйста, помогите мне написать функцию, которая принимает два аргумента: список int и индекс (int) и возвращает список целых чисел с отрицательными значениями в указанной позиции индекса в таблице.haskell recursive function

Функция будет иметь эту подпись MyReverse :: [Int]->Int->[Int].

Например: myReverse [1,2,3,4,5] 3 = [1,2,-3,4,5].

Если индекс больше длины списка или меньше 0, верните тот же список.

+6

Это пахнет как домашнее задание. Если это так, пометьте его как таковой. –

+0

'itemInverse' (или' inverseItem') будет лучшим именем, так как «reverse» подразумевает совершенно другую операцию над списками. – outis

+0

или 'negateItem'. Обратное может означать 1/x. – kennytm

ответ

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)) 

Это индексирование массива от 0; ваш пример индексов от 1, но не указан для случая n == 0. Зафиксировать его для индексации с 1 должно быть достаточно очевидным :)

Кроме того, ваша капитализация не соответствует действительности; MyReverse отличается от myReverse, и только последняя действительна как функция.

Результаты, в 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] 

Более общая версия, которая делает то же самое, используя бессмысленные определения для 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

спасибо, мое решение не работало из-за недостатка ob скобок в (-x): xs спасибо за помощь – gruber

+0

@snorlaks: Если у вас есть частичное решение, люди всегда оценят, что вы публикуете его с вопросом и говорите, что вы «Пробовал, где вы думаете, проблема и т. д. –

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

Это очень неидиоматический Haskell и очень неэффективен. – MtnViewMark

+0

Ohhh thats ttricku, но интересно, не могли бы вы объяснить этот пример для меня шаг за шагом? спасибо за помощь – gruber

+0

let j = i -1 дает вам индекс перед тем, который нужно изменить. take j xs дает вам список элементов до i "++" представляет собой список конкатенации "!!" является индексом ":" помещает отрицаемое значение на голову drop i xs drop i xs - это список xs с удаленными элементами i. Таким образом, он разбивает список на предыдущую часть части отрицания i и все после того, как я потом склеивает все это вместе – stonemetal