2013-07-05 46 views
2

基本上,我想創建一個函數,它接受一個整數列表和另一個列表(此列表可以是任何類型),並生成另一個列表,其中包含其他列表中的元素「以整數列表指定的間隔。如果我輸入:反覆調用一個函數:Haskell

IXS [2,3,1] [3,2,1]
[2,1,3]

到目前爲止,我有:

ix :: Int -> [a] -> a 
ix a [] = error "Empty list" 
ix 1 (x:xs) = x 
ix a (x:xs) = ix (a-1) xs 

ixs :: [Int] -> [a] -> [a] 
ixs [] _ = [] 
ixs _ [] = [] 
ixs (x:xs) (y) = ix x y: [] 

有了這個代碼我只得到一個返回值,如下所示:

IXS [1,2] [2,1]
[2]

如何在(x:xs)上重複調用ix函數,以便返回所需的所有值?

編輯:我想這樣做,而不使用任何標準的前奏功能。我只想使用遞歸。

回答

0

你可以逆轉的順序論點

ix' :: [a] -> Int -> a 
ix' [] a = error "Empty list" 
ix' (x:xs) 1 = x 
ix' (x:xs) a = ix' xs (a-1) 

,以使其更容易在的indeces列表映射ix

ixs' :: [a] -> [Int] -> [a] 
ixs' xs is = map (ix' xs) is 

像這樣:

> ixs' "Hello Mum" [1,5,6,1,5,6,1,5] 
"Ho Ho Ho" 

,但它會更好使用flip交換的參數 - ix'只是flip ix,所以你可以做

ixs :: [Int] -> [a] -> [a] 
ixs is xs = map (flip ix xs) is 

然後您按照您計劃的方式調用:

> ixs [1,5,6,1,5,6,1,5] "Hello Mum" 
"Ho Ho Ho" 
+1

謝謝!這真的幫助了我。我從來沒有想過使用地圖和翻轉這個功能。再次感謝! – user2548080

0

也許這樣的事情

ixs :: [Int] -> [a] -> [a] 
ixs idx a = map (`ix` a) idx 

你想要做的是在 指數索引第二列表列表地圖索引功能,在所有的值。請注意,您ix功能只是!!功能,但是從1而不是0

3

開始索引這是(幾乎)地圖的索引(「獲取的值」)第一個列表的在第二列表

import Data.List ((!!)) 
-- (!!) :: [a] -> Int -> a 

ixs :: [Int] -> [b] -> [b] 
ixs ary ixes = map (ary !!) ixes 

但你也必須通過(3 mod 3 = 0)迴繞當你指數3元素的列表,所以我們應該只映射mod在指標

ixs ary ixes = map (ary !!) (map (`mod` length ary) ixes) 

,然後我們可以簡化爲「沒有意義的小號tyle」

ixs ary = map (ary !!) . map (`mod` length ary) 

其很好地讀作‘映射索引模數組長度然後在所得到的索引的數組索引映射’。並給出正確的結果

> ixs [2,3,1] [3,2,1] 
[2,1,3] 

要打破前奏功能和Data.List功能,我們有

(!!) :: [b] -> Int -> b 
(x:_) !! 0 = x 
(_:xs) !! n 
| n > 0  = xs !! (n-1) 
| otherwise = error "List.(!!): negative argument." 
_  !! _ = error "List.(!!): index too large." 

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