2

基本的に、整数のリストと別のリスト(このリストは任意のタイプにすることができます)を取得する関数を作成し、整数のリストで指定された間隔で「他のリスト」から要素を含む別のリストを生成します. 入力した場合:

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: []

このコードでは、次のように値が 1 つだけ返されます。

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

ix関数を繰り返し呼び出して、必要なすべての値を返すにはどうすればよい(x:xs)ですか?

編集:標準のプレリュード関数を使用せずにこれを行いたいです。再帰を使いたいだけです。

4

3 に答える 3

3

これは、(ほぼ) 2 番目のリストに対する最初のリストのインデックス付け (「で値を取得する」) のマップです。

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

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

ただし、 で 3 要素のリストにインデックスを付ける場合もラップアラウンドがあるため、インデックス(3 mod 3 = 0)を単にマップする必要があります。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
于 2013-07-05T17:36:29.647 に答える
0

おそらくこのようなもの

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

やりたいことは、インデックスのリスト内のすべての値にインデックス関数をマップして、2 番目のリストにインデックスを付けることです。ix関数は単なる!!関数ですが、0 ではなく 1 からインデックス付けを開始することに注意してください。

于 2013-07-05T17:33:54.963 に答える