Haskell: просматривайте список и применяйте разные функции для каждого элемента
Мне нужно сканировать документ и накапливать вывод различных функций для каждой строки в файле. Функция, выполняемая в любой заданной строке файла, зависит от того, что находится в этой строке.
Я мог бы сделать это очень неэффективно, сделав полный просмотр файла для каждого списка, который я хотел собрать. Пример псевдокода:
at :: B.ByteString -> Maybe Atom
at line
| line == ATOM record = do stuff to return Just Atom
| otherwise = Nothing
ot :: B.ByteString -> Maybe Sheet
ot line
| line == SHEET record = do other stuff to return Just Sheet
| otherwise = Nothing
Затем я бы отобразил каждую из этих функций по всему списку строк в файле, чтобы получить полный список атомов и листов:
mapper :: [B.ByteString] -> IO ()
mapper lines = do
let atoms = mapMaybe at lines
let sheets = mapMaybe to lines
-- Do stuff with my atoms and sheets
Однако, это неэффективно, потому что я отображаю весь список строк для каждого списка, который я пытаюсь создать. Вместо этого я хочу отобразить список строк только один раз, идентифицировать каждую строку по мере ее перемещения, а затем применить соответствующую функцию и сохранить эти значения в разных списках.
Мой менталитет C хочет сделать это (псевдокод):
mapper' :: [B.ByteString] -> IO ()
mapper' lines = do
let atoms = []
let sheets = []
for line in lines:
| line == ATOM record = (atoms = atoms ++ at line)
| line == SHEET record = (sheets = sheets ++ ot line)
-- Now 'atoms' is a complete list of all the ATOM records
-- and 'sheets' is a complete list of all the SHEET records
Как это делает Haskell? Я просто не могу заставить свое мышление функционального программирования найти решение.