Haskell: Digitalize uma lista e aplique uma função diferente para cada elemento

Preciso digitalizar um documento e acumular a saída de diferentes funções para cada sequência do arquivo. A função executada em qualquer linha do arquivo depende do que está nessa linha.

Eu poderia fazer isso de maneira muito ineficiente, fazendo um passe completo pelo arquivo para todas as listas que eu quisesse coletar. Exemplo de pseudocódigo:

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

Em seguida, eu mapeia cada uma dessas funções em toda a lista de linhas do arquivo para obter uma lista completa de átomos e folhas:

mapper :: [B.ByteString] -> IO ()
mapper lines = do
    let atoms = mapMaybe at lines
    let sheets = mapMaybe to lines
    -- Do stuff with my atoms and sheets

No entanto, isso é ineficiente, porque estou pesquisando toda a lista de strings para todas as listas que estou tentando criar. Em vez disso, desejo mapear a lista de seqüências de linhas apenas uma vez, identificar cada linha à medida que estou passando por ela e aplicar a função apropriada e armazenar esses valores em listas diferente

Minha mentalidade C quer fazer isso (pseudo código):

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

Qual é a maneira Haskell de fazer isso? Simplesmente não consigo que minha mentalidade de programação funcional encontre uma solução.

questionAnswers(8)

yourAnswerToTheQuestion