В Haskell, мы можем использовать эти полезные идиомы, чтобы получить из списка, который индексированные элементов в нем:Haskell: Как сделать слияние фальсификатора/сборки в (zip [0 ..])?
indexify :: (Num i) => [a] -> [(i,a)]
indexify = zip [0..]
Однако, по реализации zip
в GHC.List
as of base-4.9.1.0
, это не будет полностью выполнять список слияния, т.е. это не приведет к генерации списка [0 ..], но будет создан список аргументов indexify
.
Конечно, есть определение, которое дает возможность обеспечить соответствующее слияние списка:
indexify' :: (Num i) => [a] -> [(i,a)]
indexify' xs = build $ \c n ->
foldr (\x r !i -> (i,x) `c` r (i+1)) (const n) xs 0
Нужно ли нам import GHC.Prim (build)
сделать это? Или существует другая реализация, которая упрощает до indexify'
?
Будет ли индексировать = пусть f! I x = (i + 1, (i, x)) в snd. картаAccumL f 0' произведение? Я считаю, что 'mapAccumL' подвержен слиянию. – Alec
@Alec Я собирался превратить ваш комментарий в ответ и принять его, но он не работает. 'mapAccumL' определяется в терминах' traverse = mapM', и он сплавляется в направлении «потребления» (т. е. использует 'foldr'), но он не сливается в направлении« производства »(т. е. не использует' build'). – gksato
Ах. Хорошая точка зрения. Должен был подумать об этом. Еще немного лучше, чем 'zip'. :) – Alec