Я хочу реализовать функцию карты только для определенных индексов, например:
mapFor :: (a -> a) -> [Int] -> [a] -> [a]
Пример будет выглядеть так.
mapFor (+10) [0,2] [1,2,3,4] == [11,2,13,4]
Подсказка: в вашем примере первым изменяемым индексом является 0-й индекс, который находится прямо в начале списка. Вероятно, вы могли бы найти способ выполнить эту операцию с первым элементом списка, а затем использовать рекурсию, чтобы сделать то же самое с остальной частью списка. Явная рекурсия НЕ будет самым эффективным способом сделать это, но если вы достаточно новичок в хаскеле, чтобы задать этот вопрос, вам почти всегда следует сначала делать это простым способом.
@arrowd Моя попытка состояла в том, чтобы использовать понимание списка, что заставило меня отображать только проиндексированные термины, но не отображало остальную часть списка. mapFor f is xs = map f [xs!!a | a <- is]
В случае выше он просто вернется [11,13]
@BorisKurova ваш подход к пониманию списка в порядке, но тогда я бы посоветовал вам нужны пары (индекс, значение): [ <something with is, f, i, and v> | (i,v) <- zip [(0::Int)..] xs ]
. Это, пожалуй, самый простой подход. Не лучший, если вы ищете максимальную эффективность.
Поиграйте с данными, чтобы найти шаблон, чтобы выполнить заданные требования:
mapFor (+1) [0,2] [100,200,300,400] == [101,200,301,400] ==
= { [ 100, 200, 300, 400 ] -- values
[ 0, 1, 2, 3 ] -- indices
[ 0, 2 ] } -- places
--------------------------------------
= (100+1) : { [200, 300, 400 ] -- values
[ 1, 2, 3 ] -- indices
[ 2 ] } -- places
--------------------------------------
= (100+1) : 200 : { [300, 400 ] -- values
[ 2, 3 ] -- indices
[ 2 ] } -- places
--------------------------------------
= (100+1) : 200 : (300+1) : { [400 ] -- values
[ 3 ] -- indices
[] } -- places
--------------------------------------
=
........
где { ... }
означает нашу трансформацию.
Тогда обобщайте! -- заменив конкретные данные символическими переменными, и вы получите работающий -- рекурсивный -- код.
mapFor op places values = g [0..] places values
where
g (i:is) (p:ps) (v:vs) -- most general case
| i == p = ....
| otherwise = ....
g _ [] _ = .... -- base case
...... -- more corner cases, if any
Убедитесь, что вы исчерпали все возможности своих шаблонов.
Благодаря @cornuz я понял это.
mapFor f is xs = [if (i `elem` is) then f v else v | (i,v) <- zip [0..] xs]
Если вы видите какие-либо проблемы, пожалуйста, дайте мне знать, чтобы я мог их исправить.
В чем проблема? Что вы пробовали?