import qualified Data.ByteString.Char8 as S
import qualified Data.ByteString.Lazy.Char8 as L
import System.IO
import System.Exit
import System.Environment
import Data.Char
me :: String
me = "rot"
usage :: String -> IO a
usage msg = do hPutStr stderr . unlines $ msg : ls
exitFailure
where ls = ["Usage: "++me++" <shifting>", "",
"A positive integer rotate each line by one character to the right.",
"Use negatives to go to the left"]
main :: IO ()
main = do args <- getArgs
rot <- case args of
[arg] | all isDigit arg -> return (rotLeft $ read arg)
['-':arg] | all isDigit arg -> return (rotRight $ read arg)
[_] -> usage "Malformed number"
[] -> usage "Not enough arguments"
_ -> usage "Too much arguments"
mapM_ (hPutLn stdout) . map (rot . toS) . L.lines =<< L.getContents
where hPutLn h x = S.hPutStrLn h x >> hFlush h
toS = foldr S.append S.empty . L.toChunks
rotLeft n s = rotRight (S.length s - n) s
rotRight n s = b `S.append` a where (a,b) = S.splitAt n s