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? Я просто не могу заставить свое мышление функционального программирования найти решение.

Ответы на вопрос(4)

Ваш ответ на вопрос