2013-07-05 42 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