[Haskell-cafe] Re: Cont, ContT and IO() - Code on hpaste
Matthias Görgens
matthias.goergens at googlemail.com
Sat Jul 4 11:45:44 EDT 2009
P.P.S. Strange it does not seem to work with the paste. So here comes
the solution by mail:
module Consolidator.BusinessLogic.ConflictsResolved
(consolidateDuplicates) where
import System.FilePath
import System.Directory
import Control.Monad (filterM)
import Control.Exception (throwIO)
import System.Environment
import Data.Maybe
import Control.Monad
import Control.Monad.Trans
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
instance (Monad m) => Monad (MaybeT m) where
(>>=) tmb_v f =
MaybeT (runMaybeT tmb_v
>>= \b_v -> case b_v of
Nothing -> return Nothing
Just v -> runMaybeT $ f v
)
return = MaybeT . return . return
instance MonadTrans MaybeT where
lift mon = MaybeT (mon >>= return . Just)
abort :: String -> MaybeT IO a
abort reason = do lift . putStrLn $ reason
MaybeT (return Nothing)
{-
The traversal is one directory deep only.
I try to find out if every immediate subdirectory contains exactly one
"*.gdr" file,
and collect the path names in a list, sgls.
Afterwards I append the contents of each such file to another file.
I want to abort the whole process as soon as I encounter a directory
that does not
include exactly one *.gdr file.
Currently I'm throwing exceptions but I'd prefer to rewrite this code
to use continuations.
-}
consolidateDuplicates :: FilePath -> MaybeT IO ()
consolidateDuplicates fp
= do dirs <- lift (getDirectoryContents fp)
recs <- lift (filterM doesDirectoryExist $ map (fp </>) $
filter (not . flip elem [".", ".."]) dirs)
sgls <- mapM checkForSingle recs
let cpy = fp </> "Korrigiert.gdr"
lift (copyFile (fp </> "Konsolidiert.gdr") cpy)
lift (mapM_ (\sgl -> do
str <- readFile sgl
appendFile cpy str) sgls)
checkForSingle :: FilePath -> MaybeT IO FilePath
checkForSingle fp = do
cnt <- lift (getDirectoryContents fp)
let fltr = filter ((== ".gdr") . takeExtension)
case fltr cnt of
[] -> abort ("The directory " ++ fp ++ " is empty")
[f] -> return (fp </> f)
_ -> abort ("There is more than one file in the directory " ++ fp)
More information about the Haskell-Cafe
mailing list