Я написал то, что, по моему мнению, было бы общей функцией в Haskell, но я не мог найти ее реализованной нигде. Из-за лучшего слова я назвал его «трансформировать».Функция «преобразование» Haskell
Что «преобразование» содержит три аргумента: список и начальное состояние, а также функцию, которая принимает элемент из списка, состояние и создает элемент для выходного списка и новое состояние. Выходной список имеет ту же длину, что и список ввода.
Это похоже на «scanl», если он также принял параметр состояния или, например, «unfoldr», если вы можете подать его в список.
В самом деле, я реализовал эту функцию ниже, двумя различными способами, которые имеют один и тот же результат:
transform1 :: (b -> c -> (a, c)) -> c -> [b] -> [a]
transform1 f init x = unfoldr f' (x, init)
where
f' ((l:ls), accum) = let (r, new_accum) = f l accum in Just (r, (ls, new_accum))
f' ([], _) = Nothing
transform2 :: (b -> c -> (a, c)) -> c -> [b] -> [a]
transform2 f init x = map fst $ tail $ scanl f' init' x where
f' (_,x) y = f y x
init' = (undefined, init)
Такого рода операции кажется довольно распространенным явлением, хотя, то есть, принимая список и ходить через него с некоторым состоянием и созданием нового списка, поэтому мне интересно, есть ли функция, которая уже существует, и я изобретаю колесо. Если это так, я просто использую это, но если нет, я могу упаковать то, что у меня есть (очень) небольшая библиотека.
'mapAccumL' похоже на функцию, которую вы ищете. – snak