<commit_before>{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Int
import qualified Data.ByteString.Lazy.Char8 as B
import qualified Args as A
import qualified Data.Text.Lazy.Encoding as E
import qualified Data.Text.Lazy as T
import Data.Maybe (isJust, fromJust)
import Control.Applicative
import Data.Monoid

data Result = Result
    (Maybe Int64)
    (Maybe Int64)
    (Maybe Int64)
    (Maybe Int64)
    (Maybe Int64)

instance Monoid Result where
    mempty = Result (Just 0) (Just 0) (Just 0) (Just 0) (Just 0)
    mappend (Result ls1 ws1 cs1 bs1 ll1) (Result ls2 ws2 cs2 bs2 ll2) =
        Result
        ((+) <$> ls1 <*> ls2)
        ((+) <$> ws1 <*> ws2)
        ((+) <$> cs1 <*> cs2)
        ((+) <$> bs1 <*> bs2)
        ((+) <$> ll1 <*> ll2)

instance Show Result where
    show (Result ls ws cs bs ll) = concat . maybePad $ filter isJust [ls,ws,cs,bs,ll]
        where maybePad (s:[]) = [show . fromJust $ s]
              maybePad ss = map (pad 8 ' ' . show . fromJust) ss

main :: IO ()
main = do
    args <- A.getArgs
    case A.files args of
         Nothing -> B.getContents >>= print . wc args
         Just fs -> wcFiles args fs >>= putStr . unlines . labelResults fs

wcFiles :: A.Args -> [FilePath] -> IO ([Result])
wcFiles args fs = mapM (wcFile args) fs
    where wcFile a f = fmap (wc a) (B.readFile f)

labelResults :: [FilePath] -> [Result] -> [String]
labelResults fs rs = zipWith (\r f -> show r ++ " " ++ f) (rs ++ [tally rs]) (fs ++ ["total"])
    where tally = foldr (<>) mempty

wc :: A.Args -> B.ByteString -> Result
wc a xs = let ls = if A.lines a then Just $ linecount xs else Nothing
              ws = if A.words a then Just $ wordcount xs else Nothing
              cs = if A.chars a then Just $ charcount xs else Nothing
              bs = if A.bytes a then Just $ bytecount xs else Nothing
              ll = if A.longest a then Just $ longest xs else Nothing
          in Result ls ws cs bs ll

linecount :: B.ByteString -> Int64
linecount = B.count '\n'

wordcount :: B.ByteString -> Int64
wordcount = fromIntegral . length . B.words

charcount :: B.ByteString -> Int64
charcount = T.length . E.decodeUtf8

bytecount :: B.ByteString -> Int64
bytecount = B.length

longest :: B.ByteString -> Int64
longest = maximum . map T.length . T.lines . E.decodeUtf8

pad :: Int -> Char -> String -> String
pad w c s = (replicate n c) ++ s
    where n = w - length s
<commit_msg>fixing tests for gnu version spacing<commit_after>{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Int
import qualified Data.ByteString.Lazy.Char8 as B
import qualified Args as A
import qualified Data.Text.Lazy.Encoding as E
import qualified Data.Text.Lazy as T
import Data.Maybe (isJust, fromJust)
import Control.Applicative
import Data.Monoid
import Data.List (intersperse)

data Result = Result
    (Maybe Int64)
    (Maybe Int64)
    (Maybe Int64)
    (Maybe Int64)
    (Maybe Int64)

instance Monoid Result where
    mempty = Result (Just 0) (Just 0) (Just 0) (Just 0) (Just 0)
    mappend (Result ls1 ws1 cs1 bs1 ll1) (Result ls2 ws2 cs2 bs2 ll2) =
        Result
        ((+) <$> ls1 <*> ls2)
        ((+) <$> ws1 <*> ws2)
        ((+) <$> cs1 <*> cs2)
        ((+) <$> bs1 <*> bs2)
        ((+) <$> ll1 <*> ll2)

instance Show Result where
    show (Result ls ws cs bs ll) = concat . maybePad $ map (show . fromJust) $ filter isJust [ls,ws,cs,bs,ll]
        where maybePad (s:[]) = [s]
              maybePad ss = intersperse " " $ map (pad 7 ' ') ss

main :: IO ()
main = do
    args <- A.getArgs
    case A.files args of
         Nothing -> B.getContents >>= print . wc args
         Just fs -> wcFiles args fs >>= putStr . unlines . labelResults fs

wcFiles :: A.Args -> [FilePath] -> IO ([Result])
wcFiles args fs = mapM (wcFile args) fs
    where wcFile a f = fmap (wc a) (B.readFile f)

labelResults :: [FilePath] -> [Result] -> [String]
labelResults (f:[]) (r:[]) = [show r ++ " " ++ f]
labelResults fs rs = zipWith (\r f -> show r ++ " " ++ f) (rs ++ [tally rs]) (fs ++ ["total"])
    where tally = foldr (<>) mempty

wc :: A.Args -> B.ByteString -> Result
wc a xs = let ls = if A.lines a then Just $ linecount xs else Nothing
              ws = if A.words a then Just $ wordcount xs else Nothing
              cs = if A.chars a then Just $ charcount xs else Nothing
              bs = if A.bytes a then Just $ bytecount xs else Nothing
              ll = if A.longest a then Just $ longest xs else Nothing
          in Result ls ws cs bs ll

linecount :: B.ByteString -> Int64
linecount = B.count '\n'

wordcount :: B.ByteString -> Int64
wordcount = fromIntegral . length . B.words

charcount :: B.ByteString -> Int64
charcount = T.length . E.decodeUtf8

bytecount :: B.ByteString -> Int64
bytecount = B.length

longest :: B.ByteString -> Int64
longest = maximum . map T.length . T.lines . E.decodeUtf8

pad :: Int -> Char -> String -> String
pad w c s = (replicate n c) ++ s
    where n = w - length s

{'fraction_non_alphanumeric': 0.12918178153970172, 'fraction_numerical': 0.019750100765820233, 'mean_word_length': 2.514872521246459, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3046181', 'n_tokens_mistral': 1748, 'n_tokens_neox': 1650, 'n_words': 618}