Как сложить число в списке - PullRequest
0 голосов
/ 02 октября 2018

Мой вопрос:

У меня есть список и число, и я хочу суммировать число в списке, чтобы я мог сделать это

Adding ls n = [x+n| x<-ls] 

, и это работает.

Мой вопрос: я хочу добавить n+1, n+2, n+3 в зависимости от длины списка.

Если я сделаю

let b = 0
Adding´ ls n = [x+adder n b| x<-ls] where adder n b= n+b,b++

, это нене работает, потому что b не продвигается, поэтому, если у меня есть Adding´ [1,3,4] 3 = [4,7,9].

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Подходить к проблеме рекурсивно.Добавьте число к первому элементу списка, затем вернитесь к хвосту списка со следующим большим номером.Повторяйте, пока у вас нет чисел.Вместо увеличения b вы начинаете новый вызов функции, в котором b имеет большее значение.

adding [] _ = []
adding (x:xs) b = x + b : adding xs (b+1)

В качестве примера рассмотрим

adding [7, 10, 7, 5] 0 == 7 + 0 : adding [10, 7, 5] 1
                       == 7     : (10 + 1 : adding [7, 5] 2)
                       == 7     : 11      : (7 + 2 : adding [5] 3)
                       == 7     : 11      : 9      : (5 + 3 : adding [] 4)
                       == 7     : 11      : 9      : 8      : []
                       == [7, 11, 9, 8]

Вы можете заменить 0 с любым начальным значением n в начальном вызове;рекурсивный вызов всегда увеличивает его.

0 голосов
/ 02 октября 2018

Вы можете использовать Data.List.mapAccumL (mapAccumL :: Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c)) для выполнения этой задачи.

Первый параметр - это функция, которая принимает два параметра a (аккумулятор) и n (элемент списка) и возвращает кортеж.В нашем случае мы увеличиваем a (аккумулятор) на 1 и отображаем текущий элемент n, добавляя аккумулятор.Результатом является кортеж, в котором первый элемент является конечным состоянием аккумулятора, а второй - конечным состоянием списка.Мы извлекаем второй элемент на snd.

Prelude> snd $ Data.List.mapAccumL (\a n -> (a+1,n+a)) 3 [1,3,4]
[4,7,9]
...