{-# LANGUAGE CPP #-}
module Conjure.Utils
( module Data.List
, module Data.Function
, module Data.Maybe
, module Data.Monoid
, module Data.Tuple
, module Data.Typeable
, count
, nubOn
, nubSort
, mzip
, groupOn
#if __GLASGOW_HASKELL__ < 710
, sortOn
#endif
, idIO
, mapHead
, sets
, headOr
, allEqual
, choices
, choicesThat
, foldr0
, indent
, indentBy
, classify
, classifyBy
, classifyOn
)
where
import Data.List
import Data.Function
import Data.Maybe
import Data.Monoid
import Data.Tuple
import Data.Typeable
import System.IO.Unsafe
import Test.LeanCheck.Stats (classify, classifyBy, classifyOn)
allEqual :: Eq a => [a] -> Bool
allEqual :: forall a. Eq a => [a] -> Bool
allEqual [] = Bool
False
allEqual [a
x] = Bool
False
allEqual [a
x,a
y] = a
x forall a. Eq a => a -> a -> Bool
== a
y
allEqual (a
x:a
y:[a]
xs) = a
x forall a. Eq a => a -> a -> Bool
== a
y Bool -> Bool -> Bool
&& forall a. Eq a => [a] -> Bool
allEqual (a
yforall a. a -> [a] -> [a]
:[a]
xs)
count :: (a -> Bool) -> [a] -> Int
count :: forall a. (a -> Bool) -> [a] -> Int
count a -> Bool
p = forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter a -> Bool
p
nubOn :: Eq b => (a -> b) -> [a] -> [a]
nubOn :: forall b a. Eq b => (a -> b) -> [a] -> [a]
nubOn a -> b
f = forall a. (a -> a -> Bool) -> [a] -> [a]
nubBy (forall a. Eq a => a -> a -> Bool
(==) forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` a -> b
f)
nubSort :: Ord a => [a] -> [a]
nubSort :: forall a. Ord a => [a] -> [a]
nubSort = forall {a}. Eq a => [a] -> [a]
nnub forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => [a] -> [a]
sort
where
nnub :: [a] -> [a]
nnub [] = []
nnub [a
x] = [a
x]
nnub (a
x:[a]
xs) = a
x forall a. a -> [a] -> [a]
: [a] -> [a]
nnub (forall a. (a -> Bool) -> [a] -> [a]
dropWhile (forall a. Eq a => a -> a -> Bool
==a
x) [a]
xs)
mzip :: Monoid a => [a] -> [a] -> [a]
mzip :: forall a. Monoid a => [a] -> [a] -> [a]
mzip [] [] = []
mzip [] [a]
ys = [a]
ys
mzip [a]
xs [] = [a]
xs
mzip (a
x:[a]
xs) (a
y:[a]
ys) = a
x forall a. Semigroup a => a -> a -> a
<> a
y forall a. a -> [a] -> [a]
: forall a. Monoid a => [a] -> [a] -> [a]
mzip [a]
xs [a]
ys
groupOn :: Eq b => (a -> b) -> [a] -> [[a]]
groupOn :: forall b a. Eq b => (a -> b) -> [a] -> [[a]]
groupOn a -> b
f = forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (forall a. Eq a => a -> a -> Bool
(==) forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` a -> b
f)
#if __GLASGOW_HASKELL__ < 710
sortOn :: Ord b => (a -> b) -> [a] -> [a]
sortOn f = sortBy (compare `on` f)
#endif
idIO :: (a -> IO ()) -> a -> a
idIO :: forall a. (a -> IO ()) -> a -> a
idIO a -> IO ()
action a
x = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
a -> IO ()
action a
x
forall (m :: * -> *) a. Monad m => a -> m a
return a
x
mapHead :: (a -> a) -> [a] -> [a]
mapHead :: forall a. (a -> a) -> [a] -> [a]
mapHead a -> a
f (a
x:[a]
xs) = a -> a
f a
x forall a. a -> [a] -> [a]
: [a]
xs
sets :: [a] -> [[a]]
sets :: forall a. [a] -> [[a]]
sets [] = [[]]
sets (a
x:[a]
xs) = forall a b. (a -> b) -> [a] -> [b]
map (a
xforall a. a -> [a] -> [a]
:) [[a]]
ss forall a. [a] -> [a] -> [a]
++ [[a]]
ss
where
ss :: [[a]]
ss = forall a. [a] -> [[a]]
sets [a]
xs
headOr :: a -> [a] -> a
headOr :: forall a. a -> [a] -> a
headOr a
x [] = a
x
headOr a
_ (a
x:[a]
xs) = a
x
choices :: [a] -> [(a,[a])]
choices :: forall a. [a] -> [(a, [a])]
choices [] = []
choices (a
x:[a]
xs) = (a
x,[a]
xs) forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map (forall {t} {b} {a}. (t -> b) -> (a, t) -> (a, b)
mapSnd (a
xforall a. a -> [a] -> [a]
:)) (forall a. [a] -> [(a, [a])]
choices [a]
xs)
where
mapSnd :: (t -> b) -> (a, t) -> (a, b)
mapSnd t -> b
f (a
x,t
y) = (a
x,t -> b
f t
y)
choicesThat :: (a -> [a] -> Bool) -> [a] -> [(a,[a])]
choicesThat :: forall a. (a -> [a] -> Bool) -> [a] -> [(a, [a])]
choicesThat a -> [a] -> Bool
(?) = forall a. (a -> Bool) -> [a] -> [a]
filter (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> [a] -> Bool
(?)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [(a, [a])]
choices
foldr0 :: (a -> a -> a) -> a -> [a] -> a
foldr0 :: forall a. (a -> a -> a) -> a -> [a] -> a
foldr0 a -> a -> a
f a
z [a]
xs | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
xs = a
z
| Bool
otherwise = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 a -> a -> a
f [a]
xs
indent :: String -> String
indent :: String -> String
indent = Int -> String -> String
indentBy Int
4
indentBy :: Int -> String -> String
indentBy :: Int -> String -> String
indentBy Int
n = [String] -> String
unlines forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a. Int -> a -> [a]
replicate Int
n Char
' ' forall a. [a] -> [a] -> [a]
++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines