Skip to content

Instantly share code, notes, and snippets.

@nominolo
Created November 29, 2012 17:56
Show Gist options
  • Save nominolo/4170774 to your computer and use it in GitHub Desktop.
Save nominolo/4170774 to your computer and use it in GitHub Desktop.
Buffer last N lines
{-# LANGUAGE ScopedTypeVariables #-}
-- Usage: something-with-lots-of-output | ./outbuffer <N>
--
-- Reads everything on stdin and outputs the last <N> lines. Keeps N
-- lines in memory, so don't make <N> too large.
module Main where
import Control.Exception as E
import Data.ByteString.Char8 as B
import Data.Sequence as S
import Data.Foldable as F
import System.Environment
main = do
lineStr:_ <- getArgs
lines <- bufferLines (read lineStr)
F.mapM_ B.putStrLn lines
safeGetLine :: IO (Maybe B.ByteString)
safeGetLine = do
l <- try B.getLine
case l of
Left (e :: IOException) -> return Nothing
Right line -> return (Just line)
bufferLines :: Int -> IO (Seq B.ByteString)
bufferLines maxLines = go S.empty
where
go acc = do
mb_line <- safeGetLine
case mb_line of
Nothing -> return acc
Just line -> do
let acc' | S.length acc >= maxLines = S.drop 1 acc
| otherwise = acc
go $! (acc' |> line)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment