У меня есть простая задача - прочитать кучу строк из файла и что-то сделать с каждой из них. За исключением первого — некоторые заголовки следует игнорировать.
Так что я решил попробовать трубопроводы.
printFile src = runResourceT $ CB.sourceFile src =$=
CT.decode CT.utf8 =$= CT.lines =$= CL.mapM_ putStrLn
Круто.
Итак, теперь я просто хочу удалить первую строку ... и, кажется, для этого есть функция -
printFile src = runResourceT $ CB.sourceFile src =$=
CT.decode CT.utf8 =$= CT.lines =$= drop 1 =$= CL.mapM_ putStrLn
Хмм - но теперь я заметил, что у drop есть сигнатура типа Sink am ()
. Кто-то предложил мне использовать экземпляр Monad для каналов и использовать drop для эффективного удаления некоторых элементов, поэтому я попробовал следующее:
drop' :: Int -> Pipe a a m ()
drop' n = do
CL.drop n
x <- await
case x of
Just v -> yield v
Nothing -> return ()
Что не проверяет тип, потому что экземпляр монады для каналов применяется только к каналам одного типа. - У раковин есть выход Void, поэтому я не могу использовать его таким образом.
Я быстро взглянул на pipe и pipe-core и заметил, что у pipe-core есть функция, которую я ожидал, где as pipe — это минимальная библиотека, но документация показывает, как она будет реализована.
Итак, я запутался — может быть, я упустил какое-то ключевое понятие.. Я видел функцию
sequence :: Sink input m output -> Conduit input m output
Но это не кажется правильной идеей, так как выходное значение равно ()
CL.sequence (CL.drop 1) :: Conduit a m ()
I я, вероятно, просто вернусь и использую lazy-io, поскольку мне действительно не нужна потоковая передача, но мне было бы интересно посмотреть, как это сделать правильно.