4
\$\begingroup\$

I've got this fairly simple program to print out each subdirectory of the working dir.

import System.Directory (listDirectory, doesDirectoryExist)

main = do
    dirs <- getDirectories
    mapM_ putStrLn dirs

-- Get a list of directories within the working directory
getDirectories :: IO [FilePath]
getDirectories = do
    contents <- listDirectory "." 
    fIO doesDirectoryExist contents

-- Filter a list with an IO predicate.
-- (In this use case, queries file system for directory status.)
fIO :: (a -> IO Bool) -> [a] -> IO [a] 
fIO f [] = return []
fIO f (x:xs) = do
    matches <- f x 
    rest <- fIO f xs
    return $ (if matches then [x] else []) ++ rest

I also attempted this implementation of the fIO function, and I'm not sure if it's legitimately less clear or if it only appears that way to me because I'm not used to reading Haskell-style syntax yet.

fIO f (x:xs) = do
    matches <- f x 
    fIO f xs >>= return . ((if matches then [x] else []) ++)

Critique Request

Being a Haskell newbie, I'm sure a professional would change some things about this implementation. I'm curious what sticks out as awkward, non-idiomatic, or opaque. I'm also curious which implementation of the two fIOs (if either) you would select, and why.

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Instead of fIO f xs >>= return . ((if matches then [x] else []) ++), you can use <$>:

([x | matches] ++) <$> fIO f xs

Applicative style would allow you to compress all this yet further:

fIO f (x:xs) = (\matches -> ([x | matches] ++)) <$> f xs <*> fIO f xs

But in the end:

fIO = filterM
\$\endgroup\$
2
  • \$\begingroup\$ Cool thank you! I hadn't encountered Applicative yet, and I like that [x | matches] syntax. Is there a name for it? I tried searching for "hasekll guard singleton or empty list" and couldn't find anything. \$\endgroup\$ Commented Jun 11, 2017 at 14:56
  • \$\begingroup\$ Look for list comprehension syntax. \$\endgroup\$
    – Gurkenglas
    Commented Jun 11, 2017 at 18:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.