{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-} ----------------------------------------------------------------------------- -- | -- Module : Numeric.Tuple -- Copyright : (c) Artem Chirkin -- License : BSD3 -- -- Maintainer : chirkin@arch.ethz.ch -- -- This module defines a set of tuple data types to substitute normal Haskell tuples. -- The reason is that @Monoid@ instances of normal tuples are lazy, -- which makes folds with arithmetic operations leak memory. -- @Semigroup@ and @Monoid@ instances of tuples in this module are strict in all their arguments. -- -- Using tuple types defined here together with @Numeric.Semigroup.foldMap'@, -- one can combine multiple monoidal fold structures in a single pass over a foldable container: -- -- >> foldMap' (T3 <$> Max <*> Sum <*> Min) $ take 100000000 ([1..] :: [Int]) -- -- The example above runs in constant space, which would not happen with normal -- GHC tuples due to strictness properties of their `mappend` implementations -- (tuple arguments are not enforced). -- -- ----------------------------------------------------------------------------- module Numeric.Tuple ( T0 (..), T1 (..), T2 (..), T3 (..), T4 (..) , T5 (..), T6 (..), T7 (..), T8 (..), T9 (..) , AsTuple (..) , foldMap' ) where import Data.Bifunctor import Data.Coerce (coerce) import Data.Data import GHC.Generics import Numeric.Semigroup data T0 = T0 deriving (Eq, Show, Read, Ord, Data, Typeable, Generic) newtype T1 a = T1 a deriving (Eq, Show, Read, Ord, Data, Typeable, Generic, Generic1) data T2 a b = T2 a b deriving (Eq, Show, Read, Ord, Data, Typeable, Generic, Generic1) data T3 a b c = T3 a b c deriving (Eq, Show, Read, Ord, Data, Typeable, Generic, Generic1) data T4 a b c d = T4 a b c d deriving (Eq, Show, Read, Ord, Data, Typeable, Generic, Generic1) data T5 a b c d e = T5 a b c d e deriving (Eq, Show, Read, Ord, Data, Typeable, Generic, Generic1) data T6 a b c d e f = T6 a b c d e f deriving (Eq, Show, Read, Ord, Data, Typeable, Generic, Generic1) data T7 a b c d e f g = T7 a b c d e f g deriving (Eq, Show, Read, Ord, Data, Typeable, Generic, Generic1) data T8 a b c d e f g h = T8 a b c d e f g h deriving (Eq, Show, Read, Ord, Data, Typeable, Generic, Generic1) data T9 a b c d e f g h i = T9 a b c d e f g h i deriving (Eq, Show, Read, Ord, Data, Typeable, Generic, Generic1) -- | This function is exactly the same as @($!)@ defined in GHC.Base, -- but it is left-associative, which makes it possible to apply -- several arguments to one function strictly. (!$) :: (a -> b) -> a -> b f !$ x = let !vx = x in f vx infixl 1 !$ {-# INLINE (!$) #-} instance Semigroup T0 where _ <> _ = T0 instance Semigroup a => Semigroup (T1 a) where (<>) = coerce ((<>) :: a -> a -> a) instance ( Semigroup a , Semigroup b ) => Semigroup (T2 a b) where (T2 !ax !bx) <> (T2 !ay !by) = T2 !$ ax <> ay !$ bx <> by instance ( Semigroup a , Semigroup b , Semigroup c ) => Semigroup (T3 a b c) where (T3 !ax !bx !cx) <> (T3 !ay !by !cy) = T3 !$ ax <> ay !$ bx <> by !$ cx <> cy instance ( Semigroup a , Semigroup b , Semigroup c , Semigroup d ) => Semigroup (T4 a b c d) where (T4 !ax !bx !cx !dx) <> (T4 !ay !by !cy !dy) = T4 !$ ax <> ay !$ bx <> by !$ cx <> cy !$ dx <> dy instance ( Semigroup a , Semigroup b , Semigroup c , Semigroup d , Semigroup e ) => Semigroup (T5 a b c d e) where (T5 !ax !bx !cx !dx !ex) <> (T5 !ay !by !cy !dy !ey) = T5 !$ ax <> ay !$ bx <> by !$ cx <> cy !$ dx <> dy !$ ex <> ey instance ( Semigroup a , Semigroup b , Semigroup c , Semigroup d , Semigroup e , Semigroup f ) => Semigroup (T6 a b c d e f) where (T6 !ax !bx !cx !dx !ex !fx) <> (T6 !ay !by !cy !dy !ey !fy) = T6 !$ ax <> ay !$ bx <> by !$ cx <> cy !$ dx <> dy !$ ex <> ey !$ fx <> fy instance ( Semigroup a , Semigroup b , Semigroup c , Semigroup d , Semigroup e , Semigroup f , Semigroup g ) => Semigroup (T7 a b c d e f g) where (T7 !ax !bx !cx !dx !ex !fx !gx) <> (T7 !ay !by !cy !dy !ey !fy !gy) = T7 !$ ax <> ay !$ bx <> by !$ cx <> cy !$ dx <> dy !$ ex <> ey !$ fx <> fy !$ gx <> gy instance ( Semigroup a , Semigroup b , Semigroup c , Semigroup d , Semigroup e , Semigroup f , Semigroup g , Semigroup h ) => Semigroup (T8 a b c d e f g h) where (T8 !ax !bx !cx !dx !ex !fx !gx !hx) <> (T8 !ay !by !cy !dy !ey !fy !gy !hy) = T8 !$ ax <> ay !$ bx <> by !$ cx <> cy !$ dx <> dy !$ ex <> ey !$ fx <> fy !$ gx <> gy !$ hx <> hy instance ( Semigroup a , Semigroup b , Semigroup c , Semigroup d , Semigroup e , Semigroup f , Semigroup g , Semigroup h , Semigroup i ) => Semigroup (T9 a b c d e f g h i) where (T9 !ax !bx !cx !dx !ex !fx !gx !hx !ix) <> (T9 !ay !by !cy !dy !ey !fy !gy !hy !iy) = T9 !$ ax <> ay !$ bx <> by !$ cx <> cy !$ dx <> dy !$ ex <> ey !$ fx <> fy !$ gx <> gy !$ hx <> hy !$ ix <> iy instance Monoid T0 where mempty = T0 mappend _ _ = T0 instance Monoid a => Monoid (T1 a) where mempty = T1 !$ mempty mappend = coerce (mappend :: a -> a -> a) instance ( Monoid a , Monoid b ) => Monoid (T2 a b) where mempty = T2 !$ mempty !$ mempty mappend (T2 !ax !bx) (T2 !ay !by) = T2 !$ mappend ax ay !$ mappend bx by instance ( Monoid a , Monoid b , Monoid c ) => Monoid (T3 a b c) where mempty = T3 !$ mempty !$ mempty !$ mempty mappend (T3 !ax !bx !cx) (T3 !ay !by !cy) = T3 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy instance ( Monoid a , Monoid b , Monoid c , Monoid d ) => Monoid (T4 a b c d) where mempty = T4 !$ mempty !$ mempty !$ mempty !$ mempty mappend (T4 !ax !bx !cx !dx) (T4 !ay !by !cy !dy) = T4 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy instance ( Monoid a , Monoid b , Monoid c , Monoid d , Monoid e ) => Monoid (T5 a b c d e) where mempty = T5 !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty mappend (T5 !ax !bx !cx !dx !ex) (T5 !ay !by !cy !dy !ey) = T5 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey instance ( Monoid a , Monoid b , Monoid c , Monoid d , Monoid e , Monoid f ) => Monoid (T6 a b c d e f) where mempty = T6 !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty mappend (T6 !ax !bx !cx !dx !ex !fx) (T6 !ay !by !cy !dy !ey !fy) = T6 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey !$ mappend fx fy instance ( Monoid a , Monoid b , Monoid c , Monoid d , Monoid e , Monoid f , Monoid g ) => Monoid (T7 a b c d e f g) where mempty = T7 !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty mappend (T7 !ax !bx !cx !dx !ex !fx !gx) (T7 !ay !by !cy !dy !ey !fy !gy) = T7 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey !$ mappend fx fy !$ mappend gx gy instance ( Monoid a , Monoid b , Monoid c , Monoid d , Monoid e , Monoid f , Monoid g , Monoid h ) => Monoid (T8 a b c d e f g h) where mempty = T8 !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty mappend (T8 !ax !bx !cx !dx !ex !fx !gx !hx) (T8 !ay !by !cy !dy !ey !fy !gy !hy) = T8 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey !$ mappend fx fy !$ mappend gx gy !$ mappend hx hy instance ( Monoid a , Monoid b , Monoid c , Monoid d , Monoid e , Monoid f , Monoid g , Monoid h , Monoid i ) => Monoid (T9 a b c d e f g h i) where mempty = T9 !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty mappend (T9 !ax !bx !cx !dx !ex !fx !gx !hx !ix) (T9 !ay !by !cy !dy !ey !fy !gy !hy !iy) = T9 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey !$ mappend fx fy !$ mappend gx gy !$ mappend hx hy !$ mappend ix iy instance Functor T1 where fmap = coerce instance Functor (T2 a) where fmap fun ~(T2 a b) = T2 a (fun b) instance Functor (T3 a b) where fmap fun ~(T3 a b c) = T3 a b (fun c) instance Functor (T4 a b c) where fmap fun ~(T4 a b c d) = T4 a b c (fun d) instance Functor (T5 a b c d) where fmap fun ~(T5 a b c d e) = T5 a b c d (fun e) instance Functor (T6 a b c d e) where fmap fun ~(T6 a b c d e f) = T6 a b c d e (fun f) instance Functor (T7 a b c d e f) where fmap fun ~(T7 a b c d e f g) = T7 a b c d e f (fun g) instance Functor (T8 a b c d e f g) where fmap fun ~(T8 a b c d e f g h) = T8 a b c d e f g (fun h) instance Functor (T9 a b c d e f g h) where fmap fun ~(T9 a b c d e f g h i) = T9 a b c d e f g h (fun i) instance Applicative T1 where pure = T1 (<*>) = coerce instance ( Monoid a ) => Applicative (T2 a) where pure = T2 !$ mempty ~(T2 !ax fun) <*> ~(T2 !ay val) = T2 !$ mappend ax ay $ fun val instance ( Monoid a , Monoid b ) => Applicative (T3 a b) where pure = T3 !$ mempty !$ mempty ~(T3 !ax !bx fun) <*> ~(T3 !ay !by val) = T3 !$ mappend ax ay !$ mappend bx by $ fun val instance ( Monoid a , Monoid b , Monoid c ) => Applicative (T4 a b c) where pure = T4 !$ mempty !$ mempty !$ mempty ~(T4 !ax !bx !cx fun) <*> ~(T4 !ay !by !cy val) = T4 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy $ fun val instance ( Monoid a , Monoid b , Monoid c , Monoid d ) => Applicative (T5 a b c d) where pure = T5 !$ mempty !$ mempty !$ mempty !$ mempty ~(T5 !ax !bx !cx !dx fun) <*> ~(T5 !ay !by !cy !dy val) = T5 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy $ fun val instance ( Monoid a , Monoid b , Monoid c , Monoid d , Monoid e ) => Applicative (T6 a b c d e) where pure = T6 !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty ~(T6 !ax !bx !cx !dx !ex fun) <*> ~(T6 !ay !by !cy !dy !ey val) = T6 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey $ fun val instance ( Monoid a , Monoid b , Monoid c , Monoid d , Monoid e , Monoid f ) => Applicative (T7 a b c d e f) where pure = T7 !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty ~(T7 !ax !bx !cx !dx !ex !fx fun) <*> ~(T7 !ay !by !cy !dy !ey !fy val) = T7 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey !$ mappend fx fy $ fun val instance ( Monoid a , Monoid b , Monoid c , Monoid d , Monoid e , Monoid f , Monoid g ) => Applicative (T8 a b c d e f g) where pure = T8 !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty ~(T8 !ax !bx !cx !dx !ex !fx !gx fun) <*> ~(T8 !ay !by !cy !dy !ey !fy !gy val) = T8 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey !$ mappend fx fy !$ mappend gx gy $ fun val instance ( Monoid a , Monoid b , Monoid c , Monoid d , Monoid e , Monoid f , Monoid g , Monoid h ) => Applicative (T9 a b c d e f g h) where pure = T9 !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty !$ mempty ~(T9 !ax !bx !cx !dx !ex !fx !gx !hx fun) <*> ~(T9 !ay !by !cy !dy !ey !fy !gy !hy val) = T9 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey !$ mappend fx fy !$ mappend gx gy !$ mappend hx hy $ fun val instance Monad T1 where m >>= k = k (coerce m) instance ( Monoid a ) => Monad (T2 a) where ~(T2 !ax x) >>= k = T2 !$ mappend ax ay $ val where ~(T2 !ay val) = k x instance ( Monoid a, Monoid b ) => Monad (T3 a b) where ~(T3 !ax !bx x) >>= k = T3 !$ mappend ax ay !$ mappend bx by $ val where ~(T3 !ay !by val) = k x instance ( Monoid a, Monoid b, Monoid c ) => Monad (T4 a b c) where ~(T4 !ax !bx !cx x) >>= k = T4 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy $ val where ~(T4 !ay !by !cy val) = k x instance ( Monoid a, Monoid b, Monoid c, Monoid d ) => Monad (T5 a b c d) where ~(T5 !ax !bx !cx !dx x) >>= k = T5 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy $ val where ~(T5 !ay !by !cy !dy val) = k x instance ( Monoid a, Monoid b, Monoid c, Monoid d , Monoid e ) => Monad (T6 a b c d e) where ~(T6 !ax !bx !cx !dx !ex x) >>= k = T6 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey $ val where ~(T6 !ay !by !cy !dy !ey val) = k x instance ( Monoid a, Monoid b, Monoid c, Monoid d , Monoid e, Monoid f ) => Monad (T7 a b c d e f) where ~(T7 !ax !bx !cx !dx !ex !fx x) >>= k = T7 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey !$ mappend fx fy $ val where ~(T7 !ay !by !cy !dy !ey !fy val) = k x instance ( Monoid a, Monoid b, Monoid c, Monoid d , Monoid e, Monoid f, Monoid g ) => Monad (T8 a b c d e f g) where ~(T8 !ax !bx !cx !dx !ex !fx !gx x) >>= k = T8 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey !$ mappend fx fy !$ mappend gx gy $ val where ~(T8 !ay !by !cy !dy !ey !fy !gy val) = k x instance ( Monoid a, Monoid b, Monoid c, Monoid d , Monoid e, Monoid f, Monoid g, Monoid h ) => Monad (T9 a b c d e f g h) where ~(T9 !ax !bx !cx !dx !ex !fx !gx !hx x) >>= k = T9 !$ mappend ax ay !$ mappend bx by !$ mappend cx cy !$ mappend dx dy !$ mappend ex ey !$ mappend fx fy !$ mappend gx gy !$ mappend hx hy $ val where ~(T9 !ay !by !cy !dy !ey !fy !gy !hy val) = k x instance Bounded T0 where minBound = T0 maxBound = T0 instance ( Bounded a ) => Bounded (T1 a) where minBound = T1 !$ minBound maxBound = T1 !$ maxBound instance ( Bounded a, Bounded b ) => Bounded (T2 a b) where minBound = T2 !$ minBound !$ minBound maxBound = T2 !$ maxBound !$ maxBound instance ( Bounded a, Bounded b, Bounded c ) => Bounded (T3 a b c) where minBound = T3 !$ minBound !$ minBound !$ minBound maxBound = T3 !$ maxBound !$ maxBound !$ maxBound instance ( Bounded a, Bounded b, Bounded c, Bounded d ) => Bounded (T4 a b c d) where minBound = T4 !$ minBound !$ minBound !$ minBound !$ minBound maxBound = T4 !$ maxBound !$ maxBound !$ maxBound !$ maxBound instance ( Bounded a, Bounded b, Bounded c, Bounded d , Bounded e ) => Bounded (T5 a b c d e) where minBound = T5 !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound maxBound = T5 !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound instance ( Bounded a, Bounded b, Bounded c, Bounded d , Bounded e, Bounded f ) => Bounded (T6 a b c d e f) where minBound = T6 !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound maxBound = T6 !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound instance ( Bounded a, Bounded b, Bounded c, Bounded d , Bounded e, Bounded f, Bounded g ) => Bounded (T7 a b c d e f g) where minBound = T7 !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound maxBound = T7 !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound instance ( Bounded a, Bounded b, Bounded c, Bounded d , Bounded e, Bounded f, Bounded g, Bounded h ) => Bounded (T8 a b c d e f g h) where minBound = T8 !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound maxBound = T8 !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound instance ( Bounded a, Bounded b, Bounded c, Bounded d , Bounded e, Bounded f, Bounded g, Bounded h, Bounded i ) => Bounded (T9 a b c d e f g h i) where minBound = T9 !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound !$ minBound maxBound = T9 !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound !$ maxBound instance Foldable T1 where foldMap = coerce foldr f z y = f (coerce y) z instance Foldable (T2 a) where foldMap f ~(T2 _ x) = f x foldr f z ~(T2 _ x) = f x z length _ = 1 null _ = False instance Foldable (T3 a b) where foldMap f ~(T3 _ _ x) = f x foldr f z ~(T3 _ _ x) = f x z length _ = 1 null _ = False instance Foldable (T4 a b c) where foldMap f ~(T4 _ _ _ x) = f x foldr f z ~(T4 _ _ _ x) = f x z length _ = 1 null _ = False instance Foldable (T5 a b c e) where foldMap f ~(T5 _ _ _ _ x) = f x foldr f z ~(T5 _ _ _ _ x) = f x z length _ = 1 null _ = False instance Foldable (T6 a b c d e) where foldMap f ~(T6 _ _ _ _ _ x) = f x foldr f z ~(T6 _ _ _ _ _ x) = f x z length _ = 1 null _ = False instance Foldable (T7 a b c d e f) where foldMap f ~(T7 _ _ _ _ _ _ x) = f x foldr f z ~(T7 _ _ _ _ _ _ x) = f x z length _ = 1 null _ = False instance Foldable (T8 a b c d e f g) where foldMap f ~(T8 _ _ _ _ _ _ _ x) = f x foldr f z ~(T8 _ _ _ _ _ _ _ x) = f x z length _ = 1 null _ = False instance Foldable (T9 a b c d e f g h) where foldMap f ~(T9 _ _ _ _ _ _ _ _ x) = f x foldr f z ~(T9 _ _ _ _ _ _ _ _ x) = f x z length _ = 1 null _ = False instance Traversable T1 where traverse f = fmap T1 . coerce f instance Traversable (T2 a) where traverse fun ~(T2 a b) = T2 a <$> fun b instance Traversable (T3 a b) where traverse fun ~(T3 a b c) = T3 a b <$> fun c instance Traversable (T4 a b c) where traverse fun ~(T4 a b c d) = T4 a b c <$> fun d instance Traversable (T5 a b c d) where traverse fun ~(T5 a b c d e) = T5 a b c d <$> fun e instance Traversable (T6 a b c d e) where traverse fun ~(T6 a b c d e f) = T6 a b c d e <$> fun f instance Traversable (T7 a b c d e f) where traverse fun ~(T7 a b c d e f g) = T7 a b c d e f <$> fun g instance Traversable (T8 a b c d e f g) where traverse fun ~(T8 a b c d e f g h) = T8 a b c d e f g <$> fun h instance Traversable (T9 a b c d e f g h) where traverse fun ~(T9 a b c d e f g h i) = T9 a b c d e f g h <$> fun i instance Bifunctor T2 where first funA ~(T2 a b) = T2 (funA a) b second funB ~(T2 a b) = T2 a (funB b) bimap funA funB ~(T2 a b) = T2 (funA a) (funB b) instance Bifunctor (T3 a) where first funA ~(T3 a b c) = T3 a (funA b) c second funB ~(T3 a b c) = T3 a b (funB c) bimap funA funB ~(T3 a b c) = T3 a (funA b) (funB c) instance Bifunctor (T4 a b) where first funA ~(T4 a b c d) = T4 a b (funA c) d second funB ~(T4 a b c d) = T4 a b c (funB d) bimap funA funB ~(T4 a b c d) = T4 a b (funA c) (funB d) instance Bifunctor (T5 a b c) where first funA ~(T5 a b c d e) = T5 a b c (funA d) e second funB ~(T5 a b c d e) = T5 a b c d (funB e) bimap funA funB ~(T5 a b c d e) = T5 a b c (funA d) (funB e) instance Bifunctor (T6 a b c d) where first funA ~(T6 a b c d e f) = T6 a b c d (funA e) f second funB ~(T6 a b c d e f) = T6 a b c d e (funB f) bimap funA funB ~(T6 a b c d e f) = T6 a b c d (funA e) (funB f) instance Bifunctor (T7 a b c d e) where first funA ~(T7 a b c d e f g) = T7 a b c d e (funA f) g second funB ~(T7 a b c d e f g) = T7 a b c d e f (funB g) bimap funA funB ~(T7 a b c d e f g) = T7 a b c d e (funA f) (funB g) instance Bifunctor (T8 a b c d e f) where first funA ~(T8 a b c d e f g h) = T8 a b c d e f (funA g) h second funB ~(T8 a b c d e f g h) = T8 a b c d e f g (funB h) bimap funA funB ~(T8 a b c d e f g h) = T8 a b c d e f (funA g) (funB h) instance Bifunctor (T9 a b c d e f g) where first funA ~(T9 a b c d e f g h i) = T9 a b c d e f g (funA h) i second funB ~(T9 a b c d e f g h i) = T9 a b c d e f g h (funB i) bimap funA funB ~(T9 a b c d e f g h i) = T9 a b c d e f g (funA h) (funB i) class AsTuple a b | a -> b, b -> a where toTuple :: a -> b fromTuple :: b -> a instance AsTuple () T0 where toTuple () = T0 fromTuple T0 = () -- instance StrictTuple a (T1 a) where -- toTuple a = T1 a -- fromTuple (T1 a) = a instance AsTuple (a,b) (T2 a b) where toTuple (a,b) = T2 a b fromTuple (T2 a b) = (a,b) instance AsTuple (a,b,c) (T3 a b c) where toTuple (a,b,c) = T3 a b c fromTuple (T3 a b c)= (a,b,c) instance AsTuple (a,b,c,d) (T4 a b c d) where toTuple (a,b,c,d) = T4 a b c d fromTuple (T4 a b c d) = (a,b,c,d) instance AsTuple (a,b,c,d,e) (T5 a b c d e) where toTuple (a,b,c,d,e) = T5 a b c d e fromTuple (T5 a b c d e) = (a,b,c,d,e) instance AsTuple (a,b,c,d,e,f) (T6 a b c d e f) where toTuple (a,b,c,d,e,f) = T6 a b c d e f fromTuple (T6 a b c d e f) = (a,b,c,d,e,f) instance AsTuple (a,b,c,d,e,f,g) (T7 a b c d e f g) where toTuple (a,b,c,d,e,f,g) = T7 a b c d e f g fromTuple (T7 a b c d e f g) = (a,b,c,d,e,f,g) instance AsTuple (a,b,c,d,e,f,g,h) (T8 a b c d e f g h) where toTuple (a,b,c,d,e,f,g,h) = T8 a b c d e f g h fromTuple (T8 a b c d e f g h) = (a,b,c,d,e,f,g,h) instance AsTuple (a,b,c,d,e,f,g,h,i) (T9 a b c d e f g h i) where toTuple (a,b,c,d,e,f,g,h,i) = T9 a b c d e f g h i fromTuple (T9 a b c d e f g h i) = (a,b,c,d,e,f,g,h,i)