Last active
August 29, 2015 14:04
-
-
Save varnie/6eccdf5141a1b590d80b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mport System.Environment | |
import System.Directory | |
import Control.Monad | |
import Data.List | |
import Control.Applicative | |
import qualified Data.ByteString.Char8 as L | |
import qualified Data.ByteString as B | |
import System.IO | |
import System.IO.Error | |
main = do | |
args <- getArgs | |
case args of | |
--1st way | |
--[ext] -> --do | |
--curDir <- getCurrentDirectory | |
--process ext curDir >>= print | |
--2nd way | |
[ext] -> getCurrentDirectory >>= process ext >>= print | |
_ -> putStrLn usage | |
`catchIOError` handler | |
handler :: IOError -> IO () | |
handler e | |
-- | isDoesNotExistError e = putStrLn "The file doesn't exist!" | |
-- | isIllegalOperation e = putStrLn "Illegal operation" | |
-- | isPermissionError e = putStrLn "Permissions error" | |
-- | isUserError e = putStrLn "User error" | |
-- | isAlreadyInUseError e = putStrLn "Already in use" | |
| otherwise = ioError e | |
process::String->FilePath->IO Int | |
process ext dir = do | |
--1st way | |
--fnames <- getDirectoryContents dir | |
--let filteredNames = filter (\x -> not $ x `elem` [".", ".."]) fnames | |
--2nd way | |
--filteredNames <- getDirectoryContents dir >>= filterM (\x -> return . not $ x `elem` [".", ".."]) | |
--3rd way | |
let filterOut = getDirectoryContents dir >>= filterM (\x -> return $ x `notElem` [".", ".."]) | |
filteredNames <- filterOut | |
--print $ "dir: " ++ dir | |
--print "files: " >> print filteredNames | |
let filesLengths = map (\fname -> do | |
let curPath = fpath dir fname | |
isFile <- doesFileExist curPath | |
isDir <- doesDirectoryExist curPath | |
if isFile | |
then if ext `isSuffixOf` fname | |
then processFileStrict curPath | |
else return 0 | |
else if isDir | |
then process ext curPath | |
else return 0 | |
) filteredNames | |
--1st way | |
fmap sum $ sequence filesLengths | |
--2nd way | |
--fmap sum ( forM filesLengths $ id ) | |
--3rd way | |
--foldM (fmap . (+)) 0 filesLengths | |
--4th way | |
--foldl (\x y -> pure (+) <*> x <*> y) (pure 0) filesLengths | |
where | |
fpath dir fname = dir ++ "/" ++ fname | |
processFile::String->IO Int | |
processFile f = readFile f >>= return . length . lines | |
processFileStrict::String->IO Int | |
processFileStrict f = withFile f ReadMode $ \hdd -> do | |
text <- B.hGetContents hdd | |
return $ length . L.lines $ text | |
usage :: String | |
usage = "usage: lines_count [extension]" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment