#haskell
#haskell
Вопрос:
Кажется, я не могу найти какую-либо информацию о функции высокого порядка, которая могла бы это сделать. Я нашел ссылку на cadd в нескольких местах, но не смог найти никакой информации в haskell api.
Я просто хочу взять список с плавающей точкой и создать из него другой список, кумулятивно добавив каждый. Исходный список всегда будет начинаться с нуля. Итак, если бы у меня был список [0,2,5,9], я бы получил список [0,2,7,16].
accumulateTime :: [Float] -> [Float]
accumulateTime (x:xs) = cadd????
у меня есть другие части этого кода, которые что-то делают, но я не могу понять, как составить этот список.
Ответ №1:
Звучит так, как будто вам нужен вариант scanl
, который связан с foldl
, но создает список промежуточных результатов. Таким образом, foldl ( ) 0
суммируя список, scanl ( ) 0
создается список частичных сумм. Здесь вы, вероятно, захотите scanl1 ( )
, который не добавляет дополнительный ноль в начале.
Prelude> scanl1 ( ) [0, 2, 5, 9]
[0,2,7,16]
Ответ №2:
Я думаю, что возможность перевести императивную версию этого кода в функциональный стиль — это хороший трюк в долгосрочной перспективе. Вот как я бы решил эту проблему на одном из этих варварских императивных языков:
var acc = 0;
for each x in xs:
acc = x acc
yield acc
Обратите внимание, что здесь у нас есть две переменные — список чисел и скользящая сумма. Когда мы преобразуем этот фрагмент кода в функциональный стиль, обычно приходится превращать циклы в (хвостовую) рекурсию, а переменные — в аргументы функции (поскольку это единственное место, где они могут «мутировать»).
accum_helper acc list
Теперь мы можем попытаться разработать базовый вариант…
accum_helper acc [] = ...
…рекурсивный случай
accum_helper acc (x:xs) = ...
…и , наконец, используйте родительскую функцию для инициализации переменной
accumulate xs = accum_helper 0 xs
Ответ №3:
Обратите внимание, что fold
функции могут использовать переменную-накопитель любого типа — даже кортеж, где один элемент представляет собой совокупную сумму, а второй элемент — список предыдущих кумулятивных сумм.
Ответ №4:
Способ менее крутой, чем ответ хаммара, но другое решение:
accumulate list = [sum $ take n list | n <- [1 .. length list]]
Комментарии:
1. Это не работает для бесконечных списков, в то время как решение Хаммара работает.