diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/git-freq.cabal b/git-freq.cabal
--- a/git-freq.cabal
+++ b/git-freq.cabal
@@ -1,47 +1,48 @@
-Name:                   git-freq
-Version:                0.0.2
-Author:                 Fujimura Daisuke<me@fujimuradaisuke.com>
-Maintainer:             Fujimura Daisuke<me@fujimuradaisuke.com>
-License:                BSD3
-License-File:           LICENSE
-Synopsis:               A Git subcommand to show total addition, deletion per file
-Description:            A Git subcommand to show total addition, deletion per file
-Cabal-Version:          >= 1.10
-Homepage:               https://github.com/fujimura/git-freq
-Build-Type:             Simple
+name: git-freq
+version: 0.0.3
+cabal-version: >=1.10
+build-type: Simple
+license: BSD3
+license-file: LICENSE
+maintainer: Fujimura Daisuke<me@fujimuradaisuke.com>
+homepage: https://github.com/fujimura/git-freq
+synopsis: A Git subcommand to show total addition, deletion per file
+description:
+    A Git subcommand to show total addition, deletion per file
+author: Fujimura Daisuke<me@fujimuradaisuke.com>
 
-Executable git-freq
-  Main-Is:              Main.hs
-  Default-Language:     Haskell2010
-  GHC-Options:          -Wall
-                        -fno-warn-name-shadowing
-  Hs-Source-Dirs:       src
-  Build-Depends:        base >= 4 && < 5
-                      , bytestring
-                      , containers
-                      , optparse-applicative
-                      , process
-                      , text
-  Other-modules:        Git.Freq
-                      , Git.Freq.Source
-                      , Git.Freq.Version
+source-repository head
+    type: git
+    location: git@github.com:fujimura/git-freq.git
 
-test-suite spec
-  Main-Is:              Spec.hs
-  Default-Language:     Haskell2010
-  GHC-Options:          -Wall
-                        -fno-warn-name-shadowing
-  Hs-Source-Dirs:       src
-                      , test
-  Type:                 exitcode-stdio-1.0
-  Build-Depends:        base
-                      , bytestring
-                      , containers
-                      , hspec
-                      , optparse-applicative
-                      , process
-                      , text
+executable git-freq
+    main-is: Main.hs
+    build-depends:
+        base >=4 && <5,
+        bytestring -any,
+        containers -any,
+        io-streams -any,
+        optparse-applicative -any,
+        process -any,
+        text -any
+    default-language: Haskell2010
+    hs-source-dirs: src
+    other-modules:
+        Git.Freq
+    ghc-options: -Wall -fno-warn-name-shadowing
 
-Source-Repository head
-  Type:                 git
-  Location:             git@github.com:fujimura/git-freq.git
+test-suite spec
+    type: exitcode-stdio-1.0
+    main-is: Spec.hs
+    build-depends:
+        base -any,
+        bytestring -any,
+        containers -any,
+        io-streams -any,
+        hspec -any,
+        optparse-applicative -any,
+        process -any,
+        text -any
+    default-language: Haskell2010
+    hs-source-dirs: src test
+    ghc-options: -Wall -fno-warn-name-shadowing
diff --git a/src/Git/Freq.hs b/src/Git/Freq.hs
--- a/src/Git/Freq.hs
+++ b/src/Git/Freq.hs
@@ -1,46 +1,46 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Git.Freq where
 
-import           Control.Arrow   ((***))
-import           Data.List       (sortBy)
-import           Data.Map.Strict (Map)
-import qualified Data.Map.Strict as Map
-import           Data.Monoid
-import           Data.Text       (Text)
-import qualified Data.Text       as T
-import qualified Data.Text.IO    as T
-import           System.Process  (runInteractiveProcess)
-import           Text.Read       (readMaybe)
+import           Control.Arrow      ((***))
+import           Data.ByteString    (ByteString)
+import           Data.List          (sortBy)
+import           Data.Map.Strict    (Map)
+import qualified Data.Map.Strict    as Map
+import           Data.Text          (Text)
+import qualified Data.Text          as T
+import qualified Data.Text.Encoding as T
+import qualified Data.Text.IO       as T
+import           Text.Read          (readMaybe)
 
-import           Git.Freq.Source (Source)
-import qualified Git.Freq.Source as Source
+import           System.IO.Streams  (InputStream)
+import qualified System.IO.Streams  as Streams
 
 type FileName = Text
 type NumStat = (Int, Int)
 type Change = (FileName, NumStat)
 type Result = Map FileName NumStat
 
-parseLine :: Text -> Maybe Change
-parseLine = go . T.splitOn (T.pack "\t")
-    where go :: [Text] -> Maybe Change
-          go (_:_:"":_) = Nothing
-          go (added:deleted:filename:_) =
-            case (readIntMaybe added, readIntMaybe deleted) of
-                (Just a, Just d) -> Just (filename, (a, d))
-                _                -> Nothing
-          go _ = Nothing
-          readIntMaybe x = readMaybe (T.unpack x) :: Maybe Int
+freq :: [FilePath] -> IO ()
+freq paths = do
+    r <- getNumStatStream paths >>= freq'
+    mapM_ render (sortResult $ Map.toList r)
 
-walk :: Source a => a -> [Change] -> IO [Change]
-walk h changes = do
-    eof <- Source.isEOF h
-    if eof then return changes
-           else do
-             l <- Source.getLine h
-             case parseLine l of
-               Just c  -> walk h (c:changes)
-               Nothing -> walk h changes
+getNumStatStream :: [FilePath] -> IO (InputStream ByteString)
+getNumStatStream paths = do
+  let args = ["log"
+             , "--numstat"
+             , "--pretty=\"%0\""
+             ] ++ paths
 
+  (_,is,_,_) <- Streams.runInteractiveProcess "git" args Nothing Nothing
+  return is
+
+freq' :: InputStream ByteString -> IO Result
+freq' is = Streams.lines is >>=
+           Streams.map (parseLine . T.decodeUtf8) >>=
+           Streams.mapMaybe id >>=
+           Streams.fold incrementChange Map.empty
+
 sumChanges :: [Change] -> Result
 sumChanges = foldl incrementChange Map.empty
 
@@ -49,24 +49,20 @@
   where
     f numstat' = Just $ maybe numstat ((a+) *** (d+)) numstat'
 
-render :: Change -> IO ()
-render (fileName,(added,deleted)) =
-    T.putStrLn . T.pack . mconcat $ [T.unpack fileName, ",",  show added, ",", show deleted]
-
 sortResult :: [Change] -> [Change]
 sortResult = let f (_,(xa,xd)) (_,(ya,yd)) = (ya+yd) `compare` (xa+xd) in sortBy f
 
-freq :: [FilePath] -> IO ()
-freq paths = do
-    let args = ["log"
-               , "--numstat"
-               , "--pretty=\"%0\""
-               ] ++ paths
-
-    (_,out,_,_) <- runInteractiveProcess "git" args Nothing Nothing
-    freq' out >>= mapM_ render
+parseLine :: Text -> Maybe Change
+parseLine = go . T.splitOn (T.pack "\t")
+    where go :: [Text] -> Maybe Change
+          go (_:_:"":_) = Nothing
+          go (added:deleted:filename:_) =
+            case (readIntMaybe added, readIntMaybe deleted) of
+                (Just a, Just d) -> Just (filename, (a, d))
+                _                -> Nothing
+          go _ = Nothing
+          readIntMaybe x = readMaybe (T.unpack x) :: Maybe Int
 
-freq' :: Source a => a -> IO [Change]
-freq' source = do
-    changes <- walk source []
-    return $ sortResult . Map.toList $ sumChanges changes
+render :: Change -> IO ()
+render (fileName,(added,deleted)) =
+    T.putStrLn . T.pack . mconcat $ [T.unpack fileName, ",",  show added, ",", show deleted]
diff --git a/src/Git/Freq/Source.hs b/src/Git/Freq/Source.hs
deleted file mode 100644
--- a/src/Git/Freq/Source.hs
+++ /dev/null
@@ -1,19 +0,0 @@
-module Git.Freq.Source
-  ( Source
-  , getLine
-  , isEOF
-  ) where
-
-import           Data.Text    (Text)
-import qualified Data.Text.IO as T
-import           Prelude      hiding (getLine)
-import           System.IO    (Handle)
-import qualified System.IO    as IO
-
-class Source s where
-    isEOF :: s -> IO Bool
-    getLine :: s -> IO Text
-
-instance Source Handle where
-    isEOF = IO.hIsEOF
-    getLine = T.hGetLine
diff --git a/src/Git/Freq/Version.hs b/src/Git/Freq/Version.hs
deleted file mode 100644
--- a/src/Git/Freq/Version.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module Git.Freq.Version
-  ( version
-  ) where
-
-version :: String
-version = "0.0.2"
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -1,32 +1,26 @@
 module Main where
 
+import           Data.Version        (showVersion)
 import           Git.Freq
-import qualified Git.Freq.Version    as Version
 import           Options.Applicative
-
+import qualified Paths_git_freq      (version)
 
-data Config = Config
-  { version :: Bool
-  , paths :: [FilePath]
-  }
+filePaths :: Parser [FilePath]
+filePaths = many (argument str (metavar "PATH..." <> help "Target paths"))
 
-config :: Parser Config
-config = Config
-  <$> switch
-      (long "version" <> short 'v' <> help "Show version")
-  <*> many
-      (argument str (metavar "PATH..." <> help "Target paths"))
+version :: Parser (a -> a)
+version = infoOption (showVersion Paths_git_freq.version)
+  (  short 'v'
+  <> long "version"
+  <> help "Print version information" )
 
 main :: IO ()
-main = do
-    (Config showVersion paths) <- execParser opts
-    if showVersion then putStrLn Version.version
-                   else freq paths
+main = execParser opts >>= freq
   where
-    opts = info (helper <*> config)
+    opts = info (helper <*> version <*> filePaths)
       ( fullDesc
       <> progDesc (unlines [ "Total addition, deletion per file will be shown as a csv in following format:"
                             , "`file name, addition, deletion`"
                             ])
 
-     <> header "git-freq - Show frequently changed code in the repository")
+     <> header "git-freq - Show frequently changed code in a repository")
