-- |Module `Containers.Quadruple` include type `Quadruple` and useful functions
--  for work with it.
--
--  `Quadruple a` is just quadruple as `(a, a, a, a)`.
module Containers.Quadruple (
    Quadruple (Quadruple),
    unQuadruple,
    toList,
    toZipList,
    fromList,
  ) where

import Control.Applicative (ZipList(..))

newtype Quadruple a = Quadruple { Quadruple a -> (a, a, a, a)
unQuadruple :: (a, a, a, a) }
    deriving (Quadruple a -> Quadruple a -> Bool
(Quadruple a -> Quadruple a -> Bool)
-> (Quadruple a -> Quadruple a -> Bool) -> Eq (Quadruple a)
forall a. Eq a => Quadruple a -> Quadruple a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Quadruple a -> Quadruple a -> Bool
$c/= :: forall a. Eq a => Quadruple a -> Quadruple a -> Bool
== :: Quadruple a -> Quadruple a -> Bool
$c== :: forall a. Eq a => Quadruple a -> Quadruple a -> Bool
Eq, Eq (Quadruple a)
Eq (Quadruple a)
-> (Quadruple a -> Quadruple a -> Ordering)
-> (Quadruple a -> Quadruple a -> Bool)
-> (Quadruple a -> Quadruple a -> Bool)
-> (Quadruple a -> Quadruple a -> Bool)
-> (Quadruple a -> Quadruple a -> Bool)
-> (Quadruple a -> Quadruple a -> Quadruple a)
-> (Quadruple a -> Quadruple a -> Quadruple a)
-> Ord (Quadruple a)
Quadruple a -> Quadruple a -> Bool
Quadruple a -> Quadruple a -> Ordering
Quadruple a -> Quadruple a -> Quadruple a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Quadruple a)
forall a. Ord a => Quadruple a -> Quadruple a -> Bool
forall a. Ord a => Quadruple a -> Quadruple a -> Ordering
forall a. Ord a => Quadruple a -> Quadruple a -> Quadruple a
min :: Quadruple a -> Quadruple a -> Quadruple a
$cmin :: forall a. Ord a => Quadruple a -> Quadruple a -> Quadruple a
max :: Quadruple a -> Quadruple a -> Quadruple a
$cmax :: forall a. Ord a => Quadruple a -> Quadruple a -> Quadruple a
>= :: Quadruple a -> Quadruple a -> Bool
$c>= :: forall a. Ord a => Quadruple a -> Quadruple a -> Bool
> :: Quadruple a -> Quadruple a -> Bool
$c> :: forall a. Ord a => Quadruple a -> Quadruple a -> Bool
<= :: Quadruple a -> Quadruple a -> Bool
$c<= :: forall a. Ord a => Quadruple a -> Quadruple a -> Bool
< :: Quadruple a -> Quadruple a -> Bool
$c< :: forall a. Ord a => Quadruple a -> Quadruple a -> Bool
compare :: Quadruple a -> Quadruple a -> Ordering
$ccompare :: forall a. Ord a => Quadruple a -> Quadruple a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (Quadruple a)
Ord)

instance Functor Quadruple where
    fmap :: (a -> b) -> Quadruple a -> Quadruple b
fmap a -> b
f (Quadruple (a
x, a
y, a
z, a
w)) = (b, b, b, b) -> Quadruple b
forall a. (a, a, a, a) -> Quadruple a
Quadruple (a -> b
f a
x, a -> b
f a
y, a -> b
f a
z, a -> b
f a
w)

instance Applicative Quadruple where
    pure :: a -> Quadruple a
pure a
x = (a, a, a, a) -> Quadruple a
forall a. (a, a, a, a) -> Quadruple a
Quadruple (a
x, a
x, a
x, a
x)
    (Quadruple (a -> b
f, a -> b
g, a -> b
h, a -> b
q)) <*> :: Quadruple (a -> b) -> Quadruple a -> Quadruple b
<*> (Quadruple (a
x, a
y, a
z, a
w)) =
        (b, b, b, b) -> Quadruple b
forall a. (a, a, a, a) -> Quadruple a
Quadruple (a -> b
f a
x, a -> b
g a
y, a -> b
h a
z, a -> b
q a
w)

instance Foldable Quadruple where
    foldr :: (a -> b -> b) -> b -> Quadruple a -> b
foldr a -> b -> b
f b
z = (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> b -> b
f b
z ([a] -> b) -> (Quadruple a -> [a]) -> Quadruple a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Quadruple a -> [a]
forall a. Quadruple a -> [a]
toList

instance Traversable Quadruple where
    sequenceA :: Quadruple (f a) -> f (Quadruple a)
sequenceA (Quadruple (f a
f, f a
g, f a
h, f a
q)) =
        (a, a, a, a) -> Quadruple a
forall a. (a, a, a, a) -> Quadruple a
Quadruple ((a, a, a, a) -> Quadruple a) -> f (a, a, a, a) -> f (Quadruple a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((,,,) (a -> a -> a -> a -> (a, a, a, a))
-> f a -> f (a -> a -> a -> (a, a, a, a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
f f (a -> a -> a -> (a, a, a, a))
-> f a -> f (a -> a -> (a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> f a
g f (a -> a -> (a, a, a, a)) -> f a -> f (a -> (a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> f a
h f (a -> (a, a, a, a)) -> f a -> f (a, a, a, a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> f a
q)

toList :: Quadruple a -> [a]
toList :: Quadruple a -> [a]
toList (Quadruple (a
x, a
y, a
z, a
w)) = [a
x, a
y, a
z, a
w]

toZipList :: Quadruple a -> ZipList a
toZipList :: Quadruple a -> ZipList a
toZipList (Quadruple (a
x, a
y, a
z, a
w)) = [a] -> ZipList a
forall a. [a] -> ZipList a
ZipList [a
x, a
y, a
z, a
w]

fromList :: MonadFail m => [a] -> m (Quadruple a)
fromList :: [a] -> m (Quadruple a)
fromList [a
x, a
y, a
z, a
w] = Quadruple a -> m (Quadruple a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Quadruple a -> m (Quadruple a)) -> Quadruple a -> m (Quadruple a)
forall a b. (a -> b) -> a -> b
$ (a, a, a, a) -> Quadruple a
forall a. (a, a, a, a) -> Quadruple a
Quadruple (a
x, a
y, a
z, a
w)
fromList [a]
_ = String -> m (Quadruple a)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Input list must contain just 4 elements"