-
Notifications
You must be signed in to change notification settings - Fork 104
/
Copy pathfindpar4.hs
55 lines (48 loc) · 1.31 KB
/
findpar4.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import System.Directory
import Control.Concurrent
import System.FilePath
import System.Environment
import Data.List hiding (find)
import GHC.Conc (getNumCapabilities)
import Text.Printf
import Control.Monad.Par.IO
import Control.Monad.Par.Class
import Control.Monad.IO.Class
import Control.Exception
-- <<main
main = do
[s,d] <- getArgs
runParIO (find s d) >>= print
-- >>
-- <<find
find :: String -> FilePath -> ParIO (Maybe FilePath)
find s d = do
fs <- liftIO $ getDirectoryContents d
let fs' = sort $ filter (`notElem` [".",".."]) fs
if any (== s) fs'
then return (Just (d </> s))
else do
let ps = map (d </>) fs'
foldr (subfind s) dowait ps []
where
dowait vs = loop (reverse vs)
loop [] = return Nothing
loop (v:vs) = do
r <- get v
case r of
Nothing -> loop vs
Just a -> return (Just a)
-- >>
-- <<subfind
subfind :: String -> FilePath
-> ([IVar (Maybe FilePath)] -> ParIO (Maybe FilePath))
-> [IVar (Maybe FilePath)] -> ParIO (Maybe FilePath)
subfind s p inner ivars = do
isdir <- liftIO $ doesDirectoryExist p
if not isdir
then inner ivars
else do v <- new -- <1>
fork (find s p >>= put v) -- <2>
inner (v : ivars) -- <3>
-- >>