Created
November 28, 2015 17:54
-
-
Save noprompt/7479cf7544bd4fe4915a to your computer and use it in GitHub Desktop.
My first Haskell script (organizes files in a directory by extension)
This file contains hidden or 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
module Main where | |
import qualified System.Directory as Directory | |
import qualified System.FilePath as FilePath | |
import Control.Monad (forM, forM_, liftM) | |
import qualified Data.HashMap.Strict as HashMap | |
import Text.Printf (printf) | |
isFile :: FilePath -> IO Bool | |
isFile = Directory.doesFileExist | |
getDirectoryFiles :: FilePath -> IO [FilePath] | |
getDirectoryFiles filePath = do | |
directoryContents <- Directory.getDirectoryContents filePath | |
files <- forM directoryContents $ \entry -> do | |
b <- isFile entry | |
if b | |
then return [entry] | |
else return [] | |
return (concat files) | |
filesByExtension :: [FilePath] -> HashMap.HashMap [Char] [FilePath] | |
filesByExtension files = | |
let | |
addFileEntry h file = | |
if FilePath.hasExtension file | |
then | |
let | |
ext = tail $ FilePath.takeExtension file | |
extFiles = HashMap.lookupDefault [] ext h | |
in | |
HashMap.insert ext (file : extFiles) h | |
else | |
h | |
in | |
foldl addFileEntry HashMap.empty files | |
main :: IO () | |
main = do | |
currentDirectory <- Directory.getCurrentDirectory | |
extensions <- liftM filesByExtension $ getDirectoryFiles currentDirectory | |
forM_ (HashMap.toList extensions) $ \(ext, files) -> | |
do | |
Directory.createDirectoryIfMissing True ext | |
forM_ files $ \file -> | |
do | |
let path = FilePath.joinPath [ext, file] | |
Directory.renameFile file path | |
printf "%s -> %s\n" file path |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment