import System.Directory import Control.Concurrent import System.FilePath import Control.Concurrent.Async import System.Environment import Data.List hiding (find) main = do [s,d] <- getArgs find s d >>= print -- < FilePath -> IO (Maybe FilePath) find s d = do fs <- getDirectoryContents d let fs' = sort $ filter (`notElem` [".",".."]) fs if any (== s) fs' then return (Just (d s)) else do let ps = map (d ) fs' -- <1> foldr (subfind s) dowait ps [] -- <2> where dowait as = loop (reverse as) -- <3> loop [] = return Nothing loop (a:as) = do -- <4> r <- wait a case r of Nothing -> loop as Just a -> return (Just a) -- >> -- < FilePath -> ([Async (Maybe FilePath)] -> IO (Maybe FilePath)) -> [Async (Maybe FilePath)] -> IO (Maybe FilePath) subfind s p inner asyncs = do isdir <- doesDirectoryExist p if not isdir then inner asyncs else withAsync (find s p) $ \a -> inner (a:asyncs) -- >>