{-# LANGUAGE CPP, FlexibleInstances, FunctionalDependencies, Safe, UnicodeSyntax #-} {-| Module : Data.Tuple.Append.Class Description : A module that defines typeclasses to prepend and append items and tuples into new tuples. Maintainer : hapytexeu+gh@gmail.com Stability : experimental Portability : POSIX A module that defines typeclasses to prepend and append items and tuples into new tuples. -} module Data.Tuple.Append.Class ( -- * Add an element to a tuple TupleAddL((<++)), TupleAddR((++>)) -- * Append two tuples , TupleAppend((+++)) ) where #if MIN_VERSION_base(4,11,0) #elif MIN_VERSION_base(4,9,0) import Data.Semigroup((<>)) #endif #if MIN_VERSION_base(4,9,0) import Data.List.NonEmpty(NonEmpty((:|)), (<|)) #endif -- | A typeclass mainly used to construct a tuple with one element extra. That element is added at the left side of the tuple. -- The typeclass is also used for a small amount of extra datatypes to make it more convenient. class TupleAddL x 𝐯 x𝐯 | x 𝐯 → x𝐯, x𝐯 → x, x𝐯 → 𝐯 where infixr 5 <++ -- | Construct a new tuple by adding the first parameter as first item in the tuple. (<++) ∷ x -- ^ The item to prepend at the left side of the tuple. → 𝐯 -- ^ The tuple containing the rest of the elements. → x𝐯 -- ^ A tuple that has one element more than the given tuple: the given item that is prepended at the left side. -- | A typeclass mainly used to construct a tuple with one element extra. That element is added at the right side of the tuple. -- The typeclass is also used for a small amount of extra data types to make it more convenient. class TupleAddR 𝐯 x 𝐯x | 𝐯 x → 𝐯x, 𝐯x → 𝐯, 𝐯x → x where infixl 5 ++> -- | Construct a new tuple by adding the second parameter as last item in the tuple. (++>) ∷ 𝐯 -- ^ The tuple containing the rest of the elements. → x -- ^ The item to append at the right side of the tuple. → 𝐯x -- ^ A tuple that has one element more than the given tuple: the given item that is appended at the right side. -- | A typeclass mainly used to append two tuples together into a tuple that contains as many elements as the sum of the number of -- elements of the two given tuples. The typeclass is also used for a small amount of extra data types to make it more convenient. class TupleAppend 𝐮 𝐯 𝐮𝐯 | 𝐮 𝐯 → 𝐮𝐯, 𝐮 𝐮𝐯 → 𝐯, 𝐯 𝐮𝐯 → 𝐮 where infixr 5 +++ -- | Construct a new tuple that contains the elements of the two given tuples. (+++) ∷ 𝐮 -- ^ The first tuple to append. → 𝐯 -- ^ The second tuple to append. → 𝐮𝐯 -- ^ A tuple that contains the items of the first and the second tuple. instance TupleAddL x [x] [x] where <++ :: x -> [x] -> [x] (<++) = (:) instance TupleAddR [x] x [x] where [x] xs ++> :: [x] -> x -> [x] ++> x x = [x] xs [x] -> [x] -> [x] forall a. [a] -> [a] -> [a] ++ [x x] instance TupleAppend [u] [u] [u] where +++ :: [u] -> [u] -> [u] (+++) = [u] -> [u] -> [u] forall a. [a] -> [a] -> [a] (++) #if MIN_VERSION_base(4,9,0) instance TupleAddL x (NonEmpty x) (NonEmpty x) where <++ :: x -> NonEmpty x -> NonEmpty x (<++) = x -> NonEmpty x -> NonEmpty x forall x. x -> NonEmpty x -> NonEmpty x (<|) instance TupleAddR (NonEmpty x) x (NonEmpty x) where ~(x x :| [x] xs) ++> :: NonEmpty x -> x -> NonEmpty x ++> x xn = x x x -> [x] -> NonEmpty x forall a. a -> [a] -> NonEmpty a :| ([x] xs [x] -> x -> [x] forall 𝐯 x 𝐯x. TupleAddR 𝐯 x 𝐯x => 𝐯 -> x -> 𝐯x ++> x xn) instance TupleAppend (NonEmpty x) (NonEmpty x) (NonEmpty x) where +++ :: NonEmpty x -> NonEmpty x -> NonEmpty x (+++) = NonEmpty x -> NonEmpty x -> NonEmpty x forall a. Semigroup a => a -> a -> a (<>) #endif