反复调用一个函数:Haskell

时间:2013-07-05 17:28:55

标签: list haskell recursion

基本上,我想创建一个函数,它接受整数列表和另一个列表(此列表可以是任何类型),并生成另一个列表,其中包含“其他列表”中的元素,其间隔由整数列表。如果我输入:

  

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]

如何在ix上重复调用(x:xs)函数,以便返回我想要的所有值?

编辑:我想在不使用任何标准前奏函数的情况下执行此操作。我只是想使用递归。

3 个答案:

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

然后我们可以简化为“无意义的风格”

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

答案 1 :(得分:0)

也许是这样的

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

您要做的是将索引函数映射到列表中的所有值 索引第二个列表的索引。请注意,您的ix函数只是!!函数,但是从1而不是0开始索引。

答案 2 :(得分:0)

您可以颠倒参数的顺序

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

可以更轻松地将ix映射到indeces列表:

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"