HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Get list of the executables in the current directory

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
directorytheexecutablesgetcurrentlist

Problem

This is what I've done;

import Control.Applicative
import Control.Monad
import qualified System.Directory as SD
main = do
    files  SD.getPermissions) files
    print exes


This works fine, but I can't help feeling that this code is somewhat redundant --- with filterM, liftA, ` and =<<` all present at once, things seem unnecessarily complicated.

How can I improve this piece of code?

For a quick reference:

SD.getCurrentDirectory :: IO FilePath
SD.getDirectoryContents :: FilePath -> IO [FilePath]
SD.executable :: Permissions -> Bool
SD.getPermissions :: FilePath -> IO Permissions


and I want to filter the contents of the current directory based on its being executable or not.

Solution

I wouldn't import System.Directory qualified, it doesn't export anything that could clash with standard names.

import Control.Applicative
import Control.Monad
import System.Directory

main :: IO ()
main = do
    files  getPermissions) files
    print exes


You can toss out the Functor and Applicative stuff and just compose Monads.

import Control.Monad
import System.Directory

main :: IO ()
main = do
    files <- getDirectoryContents =<< getCurrentDirectory
    exes <- filterM (liftM executable . getPermissions) files
    print exes


You could also get rid of reverse bind and use the forward version, it's maybe more familiar?

import Control.Monad
import System.Directory

main :: IO ()
main = do
    files >= getDirectoryContents
    exes <- filterM (liftM executable . getPermissions) files
    print exes


I'd eliminate the explicit use of bind entirely though, then it becomes easier to turn this into a function that can work on directories other than the current one.

import Control.Monad
import System.Directory

main :: IO ()
main = do
    dir  IO ()
printExecutables dir = do
    files <- getDirectoryContents dir
    exes <- filterM (liftM executable . getPermissions) files
    print exes

Code Snippets

import Control.Applicative
import Control.Monad
import System.Directory

main :: IO ()
main = do
    files <- getDirectoryContents =<< getCurrentDirectory
    exes <- filterM (liftA executable <$> getPermissions) files
    print exes
import Control.Monad
import System.Directory

main :: IO ()
main = do
    files <- getDirectoryContents =<< getCurrentDirectory
    exes <- filterM (liftM executable . getPermissions) files
    print exes
import Control.Monad
import System.Directory

main :: IO ()
main = do
    files <- getCurrentDirectory >>= getDirectoryContents
    exes <- filterM (liftM executable . getPermissions) files
    print exes
import Control.Monad
import System.Directory

main :: IO ()
main = do
    dir <- getCurrentDirectory
    printExecutables dir

printExecutables :: FilePath -> IO ()
printExecutables dir = do
    files <- getDirectoryContents dir
    exes <- filterM (liftM executable . getPermissions) files
    print exes

Context

StackExchange Code Review Q#79180, answer score: 2

Revisions (0)

No revisions yet.