2010-05-01 113 views
1

請幫我寫一個函數,該函數接受兩個參數:一個int和一個index(int)列表,並返回表中指定索引位置上具有負值的整數列表。haskell遞歸函數

函數將具有此簽名MyReverse :: [Int]->Int->[Int]

例如:myReverse [1,2,3,4,5] 3 = [1,2,-3,4,5]

如果索引大於列表的長度或小於0,則返回相同的列表。

+6

這氣味像功課。如果是這樣,請將其標記爲。 – 2010-05-01 13:10:55

+0

'itemInverse'(或'inverseItem')將是一個更好的名字,因爲「反向」意味着列表上完全不同的操作。 – outis 2010-05-01 13:12:59

+0

或'negateItem'。逆可以表示1/x。 – kennytm 2010-05-01 13:21:01

回答

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應該是相當明顯的:)

此外,您的大寫是不一致的; MyReversemyReverse不同,只有後者作爲函數有效。

結果,在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

謝謝,我的解決方案沒有工作,因爲在(-x)缺少方括號:xs 感謝您的幫助 – gruber 2010-05-01 15:31:27

+0

@snorlaks:如果您有一個部分解決方案,人們會永遠感激您發佈問題,並說出你的已經嘗試過,你認爲問題在哪裏,等等。 – 2010-05-02 22:45:45

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

這是非常不經意的Haskell,而且效率很低。 – MtnViewMark 2010-05-02 21:49:54

+0

哦,這是ttricku,但有趣的,可以請你一步一步解釋我的例子嗎? 感謝您的幫助 – gruber 2010-05-03 11:58:47

+0

讓j = i -1爲您提供剛好在需要改變的元素之前的元素的索引。 take j xs給出了我之前的元素列表 「++」是列表級聯 「!!」是索引 「:」將取反的值放在放置頭i xs 放下i xs是移除了第一個i元素的列表xs。 因此,它將列表拆分成之前我分割否定的部分和我之後的所有內容然後它將它們粘在一起 – stonemetal 2010-05-03 20:46:42