Как использовать функцию опускания канала в трубопроводе?

У меня есть простая задача - прочитать кучу строк из файла и что-то сделать с каждой из них. За исключением первого — некоторые заголовки следует игнорировать.

Так что я решил попробовать трубопроводы.

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, поскольку мне действительно не нужна потоковая передача, но мне было бы интересно посмотреть, как это сделать правильно.

9
задан Oliver 31 May 2012 в 13:58
поделиться