module Camfort.Helpers
(
Directory
, FileOrDir
, Filename
, SourceText
, checkDir
, getDir
, isDirectory
, collect
, descendBiReverseM
, descendReverseM
) where
import Data.Generics.Uniplate.Operations
import qualified Data.Generics.Str as Str
import Data.Data
import Data.List (elemIndices, union)
import qualified Data.ByteString.Char8 as B
import System.Directory
import qualified Data.Map.Lazy as Map hiding (map, (\\))
import Control.Monad.Writer.Strict
collect :: (Eq a, Ord k) => [(k, a)] -> Map.Map k [a]
collect = Map.fromListWith union . map (fmap (:[]))
type Filename = String
type Directory = String
type SourceText = B.ByteString
type FileOrDir = String
getDir :: String -> String
getDir file = let ixs = elemIndices '/' file
in if null ixs then file
else take (last $ ixs) file
checkDir f = case (elemIndices '/' f) of
[] -> return ()
ix -> let d = take (last ix) f
in createDirectoryIfMissing True d
isDirectory :: FileOrDir -> IO Bool
isDirectory s = doesDirectoryExist s
#if __GLASGOW_HASKELL__ < 800
instance Monoid x => Monad ((,) x) where
return a = (mempty, a)
(x, a) >>= k = let (x', b) = k a
in (mappend x x', b)
#endif
data Reverse f a = Reverse { unwrapReverse :: f a }
instance Functor (Reverse Str.Str) where
fmap f (Reverse s) = Reverse (fmap f s)
instance Foldable (Reverse Str.Str) where
foldMap f (Reverse x) = foldMap f x
instance Traversable (Reverse Str.Str) where
traverse _ (Reverse Str.Zero) = pure $ Reverse Str.Zero
traverse f (Reverse (Str.One x)) = (Reverse . Str.One) <$> f x
traverse f (Reverse (Str.Two x y)) = (\y x -> Reverse $ Str.Two x y)
<$> (fmap unwrapReverse . traverse f . Reverse $ y)
<*> (fmap unwrapReverse . traverse f . Reverse $ x)
descendReverseM :: (Data on, Monad m, Uniplate on) => (on -> m on) -> on -> m on
descendReverseM f x =
liftM generate . fmap unwrapReverse . traverse f . Reverse $ current
where (current, generate) = uniplate x
descendBiReverseM :: (Data from, Data to, Monad m, Biplate from to) => (to -> m to) -> from -> m from
descendBiReverseM f x =
liftM generate . fmap unwrapReverse . traverse f . Reverse $ current
where (current, generate) = biplate x