module Base.Utils
( fst3, snd3, thd3, curry3, uncurry3
, (++!), foldr2, mapAccumM, findDouble, findMultiples
) where
import Control.Monad (MonadPlus, mzero, mplus)
import Data.List (partition)
infixr 5 ++!
fst3 :: (a, b, c) -> a
fst3 :: (a, b, c) -> a
fst3 (x :: a
x, _, _) = a
x
snd3 :: (a, b, c) -> b
snd3 :: (a, b, c) -> b
snd3 (_, y :: b
y, _) = b
y
thd3 :: (a, b, c) -> c
thd3 :: (a, b, c) -> c
thd3 (_, _, z :: c
z) = c
z
curry3 :: ((a, b, c) -> d) -> a -> b -> c -> d
curry3 :: ((a, b, c) -> d) -> a -> b -> c -> d
curry3 f :: (a, b, c) -> d
f x :: a
x y :: b
y z :: c
z = (a, b, c) -> d
f (a
x,b
y,c
z)
uncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 f :: a -> b -> c -> d
f (x :: a
x, y :: b
y, z :: c
z) = a -> b -> c -> d
f a
x b
y c
z
(++!) :: [a] -> [a] -> [a]
xs :: [a]
xs ++! :: [a] -> [a] -> [a]
++! ys :: [a]
ys = if [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
xs then [a]
ys else [a]
xs
foldr2 :: (a -> b -> c -> c) -> c -> [a] -> [b] -> c
foldr2 :: (a -> b -> c -> c) -> c -> [a] -> [b] -> c
foldr2 _ z :: c
z [] _ = c
z
foldr2 _ z :: c
z _ [] = c
z
foldr2 f :: a -> b -> c -> c
f z :: c
z (x :: a
x : xs :: [a]
xs) (y :: b
y : ys :: [b]
ys) = a -> b -> c -> c
f a
x b
y ((a -> b -> c -> c) -> c -> [a] -> [b] -> c
forall a b c. (a -> b -> c -> c) -> c -> [a] -> [b] -> c
foldr2 a -> b -> c -> c
f c
z [a]
xs [b]
ys)
mapAccumM :: (Monad m, MonadPlus p) => (acc -> x -> m (acc, y)) -> acc -> [x]
-> m (acc, p y)
mapAccumM :: (acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, p y)
mapAccumM _ z :: acc
z [] = (acc, p y) -> m (acc, p y)
forall (m :: * -> *) a. Monad m => a -> m a
return (acc
z, p y
forall (m :: * -> *) a. MonadPlus m => m a
mzero)
mapAccumM f :: acc -> x -> m (acc, y)
f z :: acc
z (x :: x
x:xs :: [x]
xs) = do
(z' :: acc
z', y :: y
y) <- acc -> x -> m (acc, y)
f acc
z x
x
(z'' :: acc
z'', ys :: p y
ys) <- (acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, p y)
forall (m :: * -> *) (p :: * -> *) acc x y.
(Monad m, MonadPlus p) =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, p y)
mapAccumM acc -> x -> m (acc, y)
f acc
z' [x]
xs
(acc, p y) -> m (acc, p y)
forall (m :: * -> *) a. Monad m => a -> m a
return (acc
z'', y -> p y
forall (m :: * -> *) a. Monad m => a -> m a
return y
y p y -> p y -> p y
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` p y
ys)
findDouble :: Eq a => [a] -> Maybe a
findDouble :: [a] -> Maybe a
findDouble [] = Maybe a
forall a. Maybe a
Nothing
findDouble (x :: a
x : xs :: [a]
xs)
| a
x a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a]
xs = a -> Maybe a
forall a. a -> Maybe a
Just a
x
| Bool
otherwise = [a] -> Maybe a
forall a. Eq a => [a] -> Maybe a
findDouble [a]
xs
findMultiples :: Eq a => [a] -> [[a]]
findMultiples :: [a] -> [[a]]
findMultiples [] = []
findMultiples (x :: a
x : xs :: [a]
xs)
| [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
same = [[a]]
multiples
| Bool
otherwise = (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
same) [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: [[a]]
multiples
where (same :: [a]
same, other :: [a]
other) = (a -> Bool) -> [a] -> ([a], [a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
==a
x) [a]
xs
multiples :: [[a]]
multiples = [a] -> [[a]]
forall a. Eq a => [a] -> [[a]]
findMultiples [a]
other