{-# LANGUAGE ExistentialQuantification, Rank2Types #-}
module Util(
forceList,
gzip, universeParentBi,
exitMessage, exitMessageImpure,
getContentsUTF8, wildcardMatch
) where
import System.Exit
import System.IO
import System.IO.Unsafe
import Unsafe.Coerce
import Data.Data
import Data.Generics.Uniplate.DataOnly
import System.FilePattern
import Data.List.Extra
forceList :: [a] -> [a]
forceList :: forall a. [a] -> [a]
forceList [a]
xs = [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs Int -> [a] -> [a]
forall a b. a -> b -> b
`seq` [a]
xs
exitMessage :: String -> IO a
exitMessage :: forall a. String -> IO a
exitMessage String
msg = do
Handle -> String -> IO ()
hPutStrLn Handle
stderr String
msg
ExitCode -> IO a
forall a. ExitCode -> IO a
exitWith (ExitCode -> IO a) -> ExitCode -> IO a
forall a b. (a -> b) -> a -> b
$ Int -> ExitCode
ExitFailure Int
1
exitMessageImpure :: String -> a
exitMessageImpure :: forall a. String -> a
exitMessageImpure = IO a -> a
forall a. IO a -> a
unsafePerformIO (IO a -> a) -> (String -> IO a) -> String -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO a
forall a. String -> IO a
exitMessage
getContentsUTF8 :: IO String
getContentsUTF8 :: IO String
getContentsUTF8 = do
Handle -> TextEncoding -> IO ()
hSetEncoding Handle
stdin TextEncoding
utf8
IO String
getContents
data Box = forall a . Data a => Box a
gzip :: Data a => (forall b . Data b => b -> b -> c) -> a -> a -> Maybe [c]
gzip :: forall a c.
Data a =>
(forall b. Data b => b -> b -> c) -> a -> a -> Maybe [c]
gzip forall b. Data b => b -> b -> c
f a
x a
y | a -> Constr
forall a. Data a => a -> Constr
toConstr a
x Constr -> Constr -> Bool
forall a. Eq a => a -> a -> Bool
/= a -> Constr
forall a. Data a => a -> Constr
toConstr a
y = Maybe [c]
forall a. Maybe a
Nothing
| Bool
otherwise = [c] -> Maybe [c]
forall a. a -> Maybe a
Just ([c] -> Maybe [c]) -> [c] -> Maybe [c]
forall a b. (a -> b) -> a -> b
$ (Box -> Box -> c) -> [Box] -> [Box] -> [c]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Box -> Box -> c
op ((forall d. Data d => d -> Box) -> a -> [Box]
forall a u. Data a => (forall d. Data d => d -> u) -> a -> [u]
forall u. (forall d. Data d => d -> u) -> a -> [u]
gmapQ d -> Box
forall d. Data d => d -> Box
Box a
x) ((forall d. Data d => d -> Box) -> a -> [Box]
forall a u. Data a => (forall d. Data d => d -> u) -> a -> [u]
forall u. (forall d. Data d => d -> u) -> a -> [u]
gmapQ d -> Box
forall d. Data d => d -> Box
Box a
y)
where op :: Box -> Box -> c
op (Box a
x) (Box a
y) = a -> a -> c
forall b. Data b => b -> b -> c
f a
x (a -> a
forall a b. a -> b
unsafeCoerce a
y)
universeParent :: Data a => a -> [(Maybe a, a)]
universeParent :: forall a. Data a => a -> [(Maybe a, a)]
universeParent a
x = (Maybe a
forall a. Maybe a
Nothing,a
x) (Maybe a, a) -> [(Maybe a, a)] -> [(Maybe a, a)]
forall a. a -> [a] -> [a]
: a -> [(Maybe a, a)]
forall a. Data a => a -> [(Maybe a, a)]
f a
x
where
f :: Data a => a -> [(Maybe a, a)]
f :: forall a. Data a => a -> [(Maybe a, a)]
f a
x = [[(Maybe a, a)]] -> [(Maybe a, a)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [(a -> Maybe a
forall a. a -> Maybe a
Just a
x, a
y) (Maybe a, a) -> [(Maybe a, a)] -> [(Maybe a, a)]
forall a. a -> [a] -> [a]
: a -> [(Maybe a, a)]
forall a. Data a => a -> [(Maybe a, a)]
f a
y | a
y <- a -> [a]
forall on. Uniplate on => on -> [on]
children a
x]
universeParentBi :: (Data a, Data b) => a -> [(Maybe b, b)]
universeParentBi :: forall a b. (Data a, Data b) => a -> [(Maybe b, b)]
universeParentBi = (b -> [(Maybe b, b)]) -> [b] -> [(Maybe b, b)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap b -> [(Maybe b, b)]
forall a. Data a => a -> [(Maybe a, a)]
universeParent ([b] -> [(Maybe b, b)]) -> (a -> [b]) -> a -> [(Maybe b, b)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [b]
forall from to. Biplate from to => from -> [to]
childrenBi
wildcardMatch :: FilePattern -> String -> Bool
wildcardMatch :: String -> String -> Bool
wildcardMatch String
p String
m = let f :: String -> String
f = String -> String -> String -> String
forall a. Eq a => [a] -> [a] -> [a] -> [a]
replace String
"." String
"/" in String -> String
f String
p String -> String -> Bool
?== String -> String
f String
m