{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

#ifndef HAVE_FUNCTOR_CLASSES
-- With Data.Functor.Classes available, we use Eq1, Ord1 and Show1 to define
-- Eq, Ord and Show. When it is not available then we can use standalone
-- deriving to get them derived for us.
{-# LANGUAGE StandaloneDeriving #-}
#endif

-- |
-- Module:       $HEADER$
-- Description:  Magic classes for OverloadedRecordFields.
-- Copyright:    (c) 2016, Peter Trško
-- License:      BSD3
--
-- Maintainer:   peter.trsko@gmail.com
-- Stability:    experimental
-- Portability:  GHC specific language extensions.
--
-- Magic classes for OverloadedRecordFields.
--
-- Implementation is based on:
-- <https://github.com/adamgundry/records-prototype/blob/master/CoherentPrototype.hs>
-- by Adam Gundry under MIT License.
module Data.OverloadedRecords
    (
    -- * Usage Examples
    --
    -- $usageExamples

    -- * Oveloaded Labels
      module Data.OverloadedLabels

    -- * Overloaded Record Fields
    --
    -- ** Getter
    , FieldType
    , HasField(..)

    , Getter
    , get

    -- ** Setter, Modifier and Lens
    , UpdateType
    , ModifyField(..)
    , R
    , Rs
    , (:::)
    , Rec(..)

    , Setting
    , setting

    , Setter
    , set

    , Modifier(..)
    , modify

    , WrappedLensLike(..)
    , lns

    , ModifyRec(..)
    , weakenRec
    , strengthenRec
    , Position

    -- ** Simple Setter, Modifier and Lens
    , ModifyField'
    , fieldLens'
    , modifyField'
    , setField'

    , Setter'
    , set'

    , Modifier'
    , modify'

    , WrappedLensLike'
    , lns'

    -- ** IsLabel For Getter and Lens
    , FromArrow
    , IsFieldAccessor(..)
    )
  where

import Data.Bool (Bool(False, True))
import Data.Function (($), const)
import Data.Functor (Functor, (<$>))
import Data.Maybe (Maybe(Just, Nothing))
import Data.Proxy (Proxy)
import Data.Type.Equality (type (==))
import Data.Typeable (Typeable)
import GHC.Exts (Constraint, Proxy#, proxy#)
import GHC.Generics (Generic, Generic1)
import GHC.TypeLits (type (-), type (+), Nat, Symbol)

#ifdef HAVE_FUNCTOR_CLASSES
import Data.Eq (Eq((==)))
import Data.Functor.Classes
    ( Eq1(liftEq)
    , Ord1(liftCompare)
    , Show1(liftShowsPrec)
    , compare1
    , eq1
    , showsPrec1
    , showsUnaryWith
    )
import Data.Ord (Ord(compare))
import Text.Show (Show(showsPrec))
#else
-- Will use StandaloneDeriving to derive instances for these.
import Data.Eq (Eq)
import Data.Ord (Ord)
import Text.Show (Show)
#endif

#ifdef HAVE_NON_EMPTY_LIST
import Data.List.NonEmpty (NonEmpty((:|)))
#endif

import Data.OverloadedLabels


-- | When accessing field named @l :: Symbol@ of a record @s :: *@, then the
-- type of the value in that field is @'FieldType' l s@.
type family FieldType (l :: Symbol) (s :: *) :: *

-- | If field @l :: Symbol@ of a record @s :: *@ is set to new value which has
-- type @b :: *@, then the modified record will have type @'UpdateType' l s b@.
type family UpdateType (l :: Symbol) (s :: *) (b :: *) :: *

-- | Definition of this class is based on:
-- <https://phabricator.haskell.org/D1687>
class HasField (l :: Symbol) s a | l s -> a where
    -- | Get value of a field.
    getField :: Proxy# l -> s -> a

-- | Represents overloaded record fields that can be modified, i.e. updated.
--
-- @
-- forall l a b s t.
--   'ModifyField' l s t a b => a /= b \<==\> s /= t
-- @
--
-- In other words, if field is modified and its type has changed, then the type
-- of the record has to change as well, and vice versa. Functional dependencies
-- enforce this rule.
--
-- /Since 0.4.0.0/
class (HasField l s a) => ModifyField (l :: Symbol) s t a b
    | l s -> a, l t -> b, l s b -> t, l t a -> s
  where
    {-# MINIMAL modifyField | setField #-}

    -- | Modify overloaded field @l :: 'Symbol'@ of record @s@ using pure
    -- function @a -> b@, and produce new record @t@.
    modifyField :: Proxy# l -> (a -> b) -> s -> t
    modifyField proxy f s = setField proxy s (f (getField proxy s))

    -- | Set overloaded field @l :: 'Symbol'@ of record @s@ to value of type
    -- @b@, and produce new record @t@. Please note that there is no mention of
    -- the type @a@, therefore the compiler may not be able to derive it in
    -- some cases.
    setField :: Proxy# l -> s -> b -> t
    setField proxy s b = modifyField proxy (const b) s

    -- | Lens for overloaded field @l :: 'Symbol'@ of record @s@.
    fieldLens :: Functor f => Proxy# l -> (a -> f b) -> s -> f t
    fieldLens proxy f s = setField proxy s <$> f (getField proxy s)

-- | Same as 'ModifyField', but type-changing assignment is prohibited.
--
-- /Since 0.4.0.0/
type ModifyField' l s a = ModifyField l s s a a

-- | Same as 'setFiend', but the field type can not be changed.
--
-- /Since 0.4.0.0/
setField' :: ModifyField' l s a => Proxy# l -> s -> a -> s
setField' = setField

-- | Same as 'modifyField', but the field type can not be changed.
--
-- /Since 0.4.0.0/
modifyField' :: ModifyField' l s a => Proxy# l -> (a -> a) -> s -> s
modifyField' = modifyField

-- | Same as 'modifyField', but the field type can not be changed.
--
-- /Since 0.4.0.0/
fieldLens'
    :: (Functor f, ModifyField' l s a)
    => Proxy# l
    -> (a -> f a)
    -> s -> f s
fieldLens' = fieldLens

-- | Returns 'True' if type @a :: \*@ is a function.
type family FromArrow (a :: *) :: Bool where
    FromArrow (x -> y) = 'True
    FromArrow t        = 'False

-- | Distinguish between getter and lens.
class
    ( z ~ FromArrow x
    ) => IsFieldAccessor (l :: Symbol) x y (z :: Bool) | l y -> x
  where
    fieldAccessor :: Proxy# l -> x -> y

-- | Overloaded lens:
--
-- @
-- 'Functor' f => 'Proxy#' l -> (a -> f b) -> s -> f t
-- @
instance
    ( Functor f
    , ModifyField l s t a b
    ) => IsFieldAccessor l (a -> f b) (s -> f t) 'True
  where
    fieldAccessor = fieldLens

-- | Overloaded getter:
--
-- @
-- 'Proxy#' l -> r -> a
-- @
instance
    ( HasField l s a
    , FromArrow s ~ 'False
    ) => IsFieldAccessor l s a 'False
  where
    fieldAccessor = getField

instance IsFieldAccessor l x y (FromArrow x) => IsLabel l (x -> y) where
    fromLabel = fieldAccessor

-- | Using this type family provides more compact type signatures for multiple
-- record fields.
--
-- @
-- data V3 a = V3
--     { _x :: a
--     , _y :: a
--     , _z :: a
--     }
--   deriving Show
--
-- 'Data.OverloadedRecords.TH.overloadedRecord' def ''V3
--
-- setV3
--     :: 'R' '[\"x\" ':::' a, \"y\" ':::' a, \"z\" ':::' a] r
--     => a -> a -> a -> r -> r
-- setV3 x y z = 'set'' \#x x . 'set'' \#y y . 'set'' \#z z
-- @
--
-- >>> setV3 0 0 0 (V3 1 1 1 :: V3 Int)
-- V3 {_x = 0, _y = 0, _z = 0}
--
-- /Since 0.4.0.0/
type family R (ts :: [(Symbol, *)]) (r :: *) :: Constraint where
    R '[] r             = ()
    R ('(l, a) ': ts) r = (ModifyField' l r a, R ts r)

-- | Union\/concatenation of record constraints.
--
-- /Since 0.4.2.0/
type family Rs (cs :: [[(Symbol, *)]]) (r :: *) where
    Rs '[]       r = R '[] r
    Rs (c ': cs) r = (R c r, Rs cs r)

-- | This type alias is used for more readable type signatures when using 'R'
-- type family.
--
-- /Since 0.4.0.0/
type (:::) (l :: Symbol) (a :: *) = '(l, a)

-- | Pass polymorphic record as a value along with all necessary instances. By
-- pattern matching on 'Rec' data constructor all those instances come in to
-- scope.
--
-- Example:
--
-- @
-- {-\# LANGUAGE GADTs \#-}
--     -- May be required in addition to the basic set of language extensions.
--
-- data V3 a = V3
--     { _x :: a
--     , _y :: a
--     , _z :: a
--     }
--   deriving Show
--
-- 'Data.OverloadedRecords.TH.overloadedRecord' def ''V3
--
-- zeroV3 :: 'Rec' '[\"x\" ':::' a, \"y\" ':::' a, \"z\" ':::' a] r -> r -> r
-- zeroV3 ('Rec' r) = 'set'' \#x 0 . 'set'' \#y 0 $ 'set'' \#z 0 r
-- @
--
-- >>> zeroV3 (V3 1 1 1 :: V3 Int)
-- V3 {_x = 0, _y = 0, _z = 0}
--
-- Difference between using a constraint, via 'R' type family, and using 'Rec',
-- is that 'Rec' retains run-time proof that the record has a specified fields.
-- More about this distinction can be found for example in
-- /Hasochism: The Pleasure and Pain of Dependently Typed Haskell Programming/
-- by /Sam Lindley/ and /Conor McBride/ available on-line
-- <https://personal.cis.strath.ac.uk/conor.mcbride/pub/hasochism.pdf>.
--
-- /Since 0.4.1.0/
data Rec ctx r where
    Rec :: R ctx r => r -> Rec ctx r
  deriving (Typeable)

-- | Weakening a record constraint.
weakenRec :: Rec ((l ::: a) ': ctx) r -> Rec ctx r
weakenRec (Rec r) = Rec r

-- | Strengthening a record constraint.
strengthenRec :: ModifyField' l r a => Rec ctx r -> Rec ((l ::: a) ': ctx) r
strengthenRec (Rec r) = Rec r

#ifdef HAVE_FUNCTOR_CLASSES
instance Eq1 (Rec ctx) where
    -- :: (a -> b -> Bool) -> f a -> f b -> Bool
    liftEq f (Rec a) (Rec b) = f a b

instance Ord1 (Rec ctx) where
    -- :: (a -> b -> Ordering) -> f a -> f b -> Ordering
    liftCompare f (Rec a) (Rec b) = f a b

instance Show1 (Rec ctx) where
    -- :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS
    liftShowsPrec sp _sl d (Rec r) = showsUnaryWith sp "Rec" d r

instance Eq r => Eq (Rec ctx r) where
    (==) = eq1

instance Ord r => Ord (Rec ctx r) where
    compare = compare1

instance Show r => Show (Rec ctx r) where
    showsPrec = showsPrec1
#else
deriving instance Eq r => Eq (Rec ctx r)
deriving instance Ord r => Ord (Rec ctx r)
deriving instance Show r => Show (Rec ctx r)
#endif

-- | Internal implementation of 'ModifyRec' type class. There should be no need
-- to use it directly or to add an instance to it.
class ModifyRec# (l :: Symbol) a (cs :: [(Symbol, *)]) (n :: Nat) (b :: Bool)
  where
    getRecField# :: Proxy# '(n, b) -> Proxy# l -> Rec cs r -> a

    modifyRecField#
        :: Proxy# '(n, b) -> Proxy# l -> (a -> a) -> Rec cs r -> Rec cs r

    setRecField# :: Proxy# '(n, b) -> Proxy# l -> Rec cs r -> a -> Rec cs r

    -- TODO:
    --
    -- Find a way how to do type changing modification and assignment:
    --
    --   modifyRecField#
    --       :: Proxy# '(n, nb) -> Proxy# l -> (a -> b) -> Rec cs r -> Rec cs s
    --
    --   setRecField#
    --       :: Proxy# '(n, nb) -> Proxy# l -> Rec cs r -> b -> Rec cs s
    --
    -- This would probably require to construct new record constraint with the
    -- member (l, a) changed to (l, b).

instance (cs ~ ((l ::: a) ': cs')) => ModifyRec# l a cs 0 'True where
    getRecField# _ p (Rec r) = getField p r
    modifyRecField# _ p f (Rec r) = Rec (modifyField p f r)
    setRecField# _ p (Rec r) a = Rec (setField p r a)

instance
    ( cs ~ ((l' ::: b) ': cs')
    , n' ~ (n - 1)
    , ModifyRec# l a cs' n' (n' == 0)
    ) => ModifyRec# l a cs n 'False
  where
    getRecField# _ p r =
        getRecField# (proxy# :: Proxy# '(n', n' == 0)) p (weakenRec r)

    modifyRecField# _ p f r@(Rec _) = strengthenRec
        $ modifyRecField# (proxy# :: Proxy# '(n', n' == 0)) p f (weakenRec r)

    setRecField# _ p r@(Rec _) a = strengthenRec
        $ setRecField# (proxy# :: Proxy# '(n', n' == 0)) p (weakenRec r) a

-- | Calculate position of @(l :: Symbol, a :: *)@ in type level list @(cs ::
-- [(Symbol, *)])@. It is used to move through type level list via the type
-- class instance chain until the correct element is reached.
type family Position (l :: Symbol) (a :: *) (cs :: [(Symbol, *)]) :: Nat where
    Position l a ('(l, a) ': cs)  = 0
    Position l a (any     ': cs)  = 1 + Position l a cs

-- | This type class provides functionality as 'HasField' and 'ModifyField',
-- but for overloaded records wrapped in 'Rec' type.
class
    ( ModifyRec# l a cs (Position l a cs) (Position l a cs == 0)
    ) => ModifyRec (l :: Symbol) a (cs :: [(Symbol, *)])
  where
    getRecField :: Proxy# l -> Rec cs r -> a
    getRecField = getRecField#
        (proxy# :: Proxy# '(Position l a cs, Position l a cs == 0))

    modifyRecField :: Proxy# l -> (a -> a) -> Rec cs r -> Rec cs r
    modifyRecField = modifyRecField#
        (proxy# :: Proxy# '(Position l a cs, Position l a cs == 0))

    setRecField :: Proxy# l -> Rec cs r -> a -> Rec cs r
    setRecField = setRecField#
        (proxy# :: Proxy# '(Position l a cs, Position l a cs == 0))

instance
    ( ModifyRec# l a cs (Position l a cs) (Position l a cs == 0)
    ) => ModifyRec l a cs

-- {{{ Getter -----------------------------------------------------------------

-- | Provides alternative to the \"native\" 'IsLabel' instance for getter.
-- Since mixing getter instance and lens instance for 'IsLabel' on polymorphic
-- records is not possible, one may want to use 'Getter' as an alternative.
--
-- /Since 0.4.1.0/
newtype Getter s a = Getter (s -> a)
  deriving (Generic, Generic1, Typeable)

-- | /Since 0.4.1.0/
instance (HasField l s a) => IsLabel l (Getter s a) where
    fromLabel proxy = Getter (getField proxy)

-- | Extract a getter function from overloaded label.
--
-- Example:
--
-- @
-- newtype Bar a = Bar {_bar :: a}
--
-- overloadedRecord ''Bar
-- @
--
-- >>> get #bar (Bar False)
-- False
--
-- /Since 0.4.1.0/
get :: Getter s a -> s -> a
get (Getter f) = f
{-# INLINE get #-}

-- }}} Getter -----------------------------------------------------------------

-- {{{ Setter -----------------------------------------------------------------

-- | 'Setting' is just a form of a 'Modifier' that allows us to specify what
-- was the original type of the value we are changing.
--
-- See also 'Setter', 'Setter'', 'Modifier', and 'Modifier''.
--
-- /Since 0.4.0.0/
type Setting a s t b = Modifier s t a b

-- | Same as 'set', but allows us to use phantom type to restrict the type of a
-- value before it was changed.
--
-- @
-- newtype Bar a = Bar {_bar :: a}
--   deriving Show
--
-- overloadedRecord ''Bar
-- @
--
-- Now we can use 'setting' to change the value stored in @Bar@. The type
-- signature in following example is not required, it is what type checker
-- would infer.
--
-- @
-- 'setting' \#bar ('Proxy' @Int) False :: Bar Int -> Bar Bool
-- @
--
-- /Since 0.4.0.0/
setting :: Setting a s t b -> Proxy a -> b -> s -> t
setting x _proxy b = modify x (const b)

-- | Wrapper for a set function, lens naming convention is used for type
-- variables. Its instance for 'IsLabel' forces overloaded label to behave as a
-- setter. We could also define 'Setter' as:
--
-- @
-- type 'Setter' s t b = forall a. 'Setting' a s t b
-- @
--
-- Notice that the @forall a@ forbids us from stating what exactly it is,
-- therefore functional dependencies in 'ModifyField' type class have to be
-- able to uniquely identify it. If that is not possible, then we may have to
-- use explicit type signature.
--
-- See also 'Setting', 'Setter'', 'Modifier', and 'Modifier''.
--
-- /Definition changed in 0.4.0.0/
type Setter s t b = forall a. Modifier s t a b

-- | Extract set function from 'Setter'. Using 'Modifier' instance for
-- 'IsLabel' forces overloaded label to behave as a setter.
--
-- Usage example:
--
-- @
-- newtype Bar a = Bar {_bar :: a}
--   deriving Show
--
-- overloadedRecord ''Bar
-- @
--
-- >>> set #bar (Nothing :: Maybe Int) (Bar (Just False))
-- Bar {_bar = Nothing}
set :: Setter s t b -> b -> s -> t
set m b = modify m (const b)
{-# INLINE set #-}

-- | Simple 'Setter' which forbids changing the field type. It can be also
-- defined in terms of 'Setting':
--
-- @
-- type 'Setter'' s a = 'Setting' a s s a
-- @
--
-- See also 'Setting', 'Setter', 'Modifier', and 'Modifier''.
--
-- /Definition changed in 0.4.0.0/
type Setter' s a = Modifier' s a

-- | Same as 'set', but the field type can not be changed.
set' :: Setter' s a -> a -> s -> s
set' m a = modify' m (const a)
{-# INLINE set' #-}

-- }}} Setter -----------------------------------------------------------------

-- {{{ Modifier ---------------------------------------------------------------

-- | Wrapper for a modification function, lens naming convention is used for
-- type variables. Its instance for 'IsLabel' forces overloaded label to behave
-- as a modification function.
--
-- See also 'Modifier'', 'Setting', 'Setter', and 'Setter''.
--
-- /Since 0.4.0.0/
newtype Modifier s t a b = Modifier ((a -> b) -> s -> t)
  deriving (Generic, Typeable)

-- | /Since 0.4.0.0/
instance (ModifyField l s t a b) => IsLabel l (Modifier s t a b) where
    fromLabel proxy = Modifier (modifyField proxy)

-- | Modify field value using provided function.
--
-- /Since 0.4.0.0/
modify :: Modifier s t a b -> (a -> b) -> s -> t
modify (Modifier f) = f

-- | Simple 'Modifier' which forbids changing the field type.
--
-- See also 'Modifier', 'Modifier'', 'Setting', 'Setter', and 'Setter''.
--
-- /Since 0.4.0.0/
type Modifier' s a = Modifier s s a a

-- | Same as 'modify', but the field type can not be changed.
--
-- /Since 0.4.0.0/
modify' :: Modifier' s a -> (a -> a) -> s -> s
modify' = modify

-- }}} Modifier ---------------------------------------------------------------

-- {{{ Lens -------------------------------------------------------------------

-- | /Since 0.4.2.0/
newtype WrappedLensLike f s t a b = WrappedLensLike ((a -> f b) -> s -> f t)

-- | /Since 0.4.2.0/
instance
    ( Functor f
    , ModifyField l s t a b
    ) => IsLabel l (WrappedLensLike f s t a b)
  where
    fromLabel proxy = WrappedLensLike (fieldLens proxy)

-- | /Since 0.4.2.0/
type WrappedLensLike' f s a = WrappedLensLike f s s a a

-- | /Since 0.4.2.0/
lns :: WrappedLensLike f s t a b -> (a -> f b) -> s -> f t
lns (WrappedLensLike l) = l
{-# INLINE lns #-}

-- | /Since 0.4.2.0/
lns' :: WrappedLensLike' f s a -> (a -> f a) -> s -> f s
lns' (WrappedLensLike l) = l
{-# INLINE lns' #-}

-- }}} Lens -------------------------------------------------------------------

-- {{{ Instances --------------------------------------------------------------

-- {{{ Instances -- Tuples ----------------------------------------------------

-- {{{ Instances -- Tuples -- 2-tuple (pair) ----------------------------------

-- | /Since 0.4.0.0/
type instance FieldType "fst" (a, b) = a

-- | /Since 0.4.0.0/
type instance UpdateType "fst" (a, b) a' = (a', b)

-- | /Since 0.4.0.0/
type instance FieldType "snd" (a, b) = b

-- | /Since 0.4.0.0/
type instance UpdateType "snd" (a, b) b' = (a, b')

-- | /Since 0.4.0.0/
type instance FieldType "curry" ((a, b) -> c) = a -> b -> c

-- | /Since 0.4.0.0/
instance HasField "fst" (a, b) a where
    getField _proxy (a, _) = a

-- | /Since 0.4.0.0/
instance HasField "snd" (a, b) b where
    getField _proxy (_, b) = b

-- | /Since 0.4.0.0/
instance HasField "curry" ((a, b) -> c) (a -> b -> c) where
    getField _proxy f a b = f (a, b)

-- | /Since 0.4.0.0/
instance ModifyField "fst" (a, b) (a', b) a a' where
    modifyField _proxy f (a, b) = (f a, b)
    setField _proxy (_, b) a = (a, b)

-- | /Since 0.4.0.0/
instance ModifyField "snd" (a, b) (a, b') b b' where
    modifyField _proxy f (a, b) = (a, f b)
    setField _proxy (a, _) b = (a, b)

-- }}} Instances -- Tuples -- 2-tuple (pair) ----------------------------------

-- {{{ Instances -- Tuples -- 3-tuple (triplet) -------------------------------

-- | /Since 0.4.0.0/
type instance FieldType "fst" (a, b, c) = a

-- | /Since 0.4.0.0/
type instance UpdateType "fst" (a, b, c) a' = (a', b, c)

-- | /Since 0.4.0.0/
type instance FieldType "snd" (a, b, c) = b

-- | /Since 0.4.0.0/
type instance UpdateType "snd" (a, b, c) b' = (a, b', c)

-- | /Since 0.4.0.0/
type instance FieldType "thd" (a, b, c) = c

-- | /Since 0.4.0.0/
type instance UpdateType "thd" (a, b, c) c' = (a, b, c')

-- | /Since 0.4.0.0/
type instance FieldType "curry" ((a, b, c) -> d) = a -> b -> c -> d

-- | /Since 0.4.0.0/
instance HasField "fst" (a, b, c) a where
    getField _proxy (a, _, _) = a

-- | /Since 0.4.0.0/
instance HasField "snd" (a, b, c) b where
    getField _proxy (_, b, _) = b

-- | /Since 0.4.0.0/
instance HasField "thd" (a, b, c) c where
    getField _proxy (_, _, c) = c

-- | /Since 0.4.0.0/
instance HasField "curry" ((a, b, c) -> d) (a -> b -> c -> d) where
    getField _proxy f a b c = f (a, b, c)

-- | /Since 0.4.0.0/
instance ModifyField "fst" (a, b, c) (a', b, c) a a' where
    modifyField _proxy f (a, b, c) = (f a, b, c)
    setField _proxy (_, b, c) a = (a, b, c)

-- | /Since 0.4.0.0/
instance ModifyField "snd" (a, b, c) (a, b', c) b b' where
    modifyField _proxy f (a, b, c) = (a, f b, c)
    setField _proxy (a, _, c) b = (a, b, c)

-- | /Since 0.4.0.0/
instance ModifyField "thd" (a, b, c) (a, b, c') c c' where
    modifyField _proxy f (a, b, c) = (a, b, f c)
    setField _proxy (a, b, _) c = (a, b, c)

-- }}} Instances -- Tuples -- 3-tuple (triplet) -------------------------------

-- {{{ Instances -- Tuples -- 4-tuple (quad) ----------------------------------

-- | /Since 0.4.0.0/
type instance FieldType "fst" (a1, a2, a3, a4) = a1

-- | /Since 0.4.0.0/
type instance UpdateType "fst" (a1, a2, a3, a4) a1' = (a1', a2, a3, a4)

-- | /Since 0.4.0.0/
type instance FieldType "snd" (a1, a2, a3, a4) = a2

-- | /Since 0.4.0.0/
type instance UpdateType "snd" (a1, a2, a3, a4) a2' = (a1, a2', a3, a4)

-- | /Since 0.4.0.0/
type instance FieldType "thd" (a1, a2, a3, a4) = a3

-- | /Since 0.4.0.0/
type instance UpdateType "thd" (a1, a2, a3, a4) a3' = (a1, a3', a3, a4)

-- | /Since 0.4.0.0/
type instance FieldType "curry" ((a1, a2, a3, a4) -> r) =
    a1 -> a2 -> a3 -> a4 -> r

-- | /Since 0.4.0.0/
instance HasField "fst" (a1, a2, a3, a4) a1 where
    getField _proxy (a1, _, _, _) = a1

-- | /Since 0.4.0.0/
instance HasField "snd" (a1, a2, a3, a4) a2 where
    getField _proxy (_, a2, _, _) = a2

-- | /Since 0.4.0.0/
instance HasField "thd" (a1, a2, a3, a4) a3 where
    getField _proxy (_, _, a3, _) = a3

-- | /Since 0.4.0.0/
instance ModifyField "fst" (a1, a2, a3, a4) (a1', a2, a3, a4) a1 a1' where
    modifyField _proxy f (a1, a2, a3, a4) = (f a1, a2, a3, a4)
    setField _proxy (_, a2, a3, a4) a1 = (a1, a2, a3, a4)

-- | /Since 0.4.0.0/
instance ModifyField "snd" (a1, a2, a3, a4) (a1, a2', a3, a4) a2 a2' where
    modifyField _proxy f (a1, a2, a3, a4) = (a1, f a2, a3, a4)
    setField _proxy (a1, _, a3, a4) a2 = (a1, a2, a3, a4)

-- | /Since 0.4.0.0/
instance ModifyField "thd" (a1, a2, a3, a4) (a1, a2, a3', a4) a3 a3' where
    modifyField _proxy f (a1, a2, a3, a4) = (a1, a2, f a3, a4)
    setField _proxy (a1, a2, _, a4) a3 = (a1, a2, a3, a4)

-- | /Since 0.4.0.0/
instance HasField "curry" ((a1, a2, a3, a4) -> r) (a1 -> a2 -> a3 -> a4 -> r)
  where
    getField _proxy f a1 a2 a3 a4 = f (a1, a2, a3, a4)

-- }}} Instances -- Tuples -- 4-tuple (quad) ----------------------------------

-- {{{ Instances -- Tuples -- 5-tuple -----------------------------------------

-- | /Since 0.4.0.0/
type instance FieldType "fst" (a1, a2, a3, a4, a5) = a1

-- | /Since 0.4.0.0/
type instance UpdateType "fst" (a1, a2, a3, a4, a5) a1' = (a1', a2, a3, a4, a5)

-- | /Since 0.4.0.0/
type instance FieldType "snd" (a1, a2, a3, a4, a5) = a2

-- | /Since 0.4.0.0/
type instance UpdateType "snd" (a1, a2, a3, a4, a5) a2' = (a1, a2', a3, a4, a5)

-- | /Since 0.4.0.0/
type instance FieldType "thd" (a1, a2, a3, a4, a5) = a3

-- | /Since 0.4.0.0/
type instance UpdateType "thd" (a1, a2, a3, a4, a5) a3' = (a1, a2, a3', a4, a5)

-- | /Since 0.4.0.0/
type instance FieldType "curry" ((a1, a2, a3, a4, a5) -> r) =
    a1 -> a2 -> a3 -> a4 -> a5 -> r

-- | /Since 0.4.0.0/
instance HasField "fst" (a1, a2, a3, a4, a5) a1 where
    getField _proxy (a1, _, _, _, _) = a1

-- | /Since 0.4.0.0/
instance HasField "snd" (a1, a2, a3, a4, a5) a2 where
    getField _proxy (_, a2, _, _, _) = a2

-- | /Since 0.4.0.0/
instance HasField "thd" (a1, a2, a3, a4, a5) a3 where
    getField _proxy (_, _, a3, _, _) = a3

-- | /Since 0.4.0.0/
instance ModifyField "fst" (a1, a2, a3, a4, a5) (a1', a2, a3, a4, a5) a1 a1'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5) = (f a1, a2, a3, a4, a5)
    setField _proxy (_, a2, a3, a4, a5) a1 = (a1, a2, a3, a4, a5)

-- | /Since 0.4.0.0/
instance
    ModifyField "snd" (a1, a2, a3, a4, a5) (a1, a2', a3, a4, a5) a2 a2'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5) = (a1, f a2, a3, a4, a5)
    setField _proxy (a1, _, a3, a4, a5) a2 = (a1, a2, a3, a4, a5)

-- | /Since 0.4.0.0/
instance
    ModifyField "thd" (a1, a2, a3, a4, a5) (a1, a2, a3', a4, a5) a3 a3'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5) = (a1, a2, f a3, a4, a5)
    setField _proxy (a1, a2, _, a4, a5) a3 = (a1, a2, a3, a4, a5)

-- | /Since 0.4.0.0/
instance
    HasField "curry" ((a1, a2, a3, a4, a5) -> r)
        (a1 -> a2 -> a3 -> a4 -> a5 -> r)
  where
    getField _proxy f a1 a2 a3 a4 a5 = f (a1, a2, a3, a4, a5)

-- }}} Instances -- Tuples -- 5-tuple -----------------------------------------

-- {{{ Instances -- Tuples -- 6-tuple -----------------------------------------

-- | /Since 0.4.0.0/
type instance FieldType "fst" (a1, a2, a3, a4, a5, a6) = a1

-- | /Since 0.4.0.0/
type instance UpdateType "fst" (a1, a2, a3, a4, a5, a6) a1' =
    (a1', a2, a3, a4, a5, a6)

-- | /Since 0.4.0.0/
type instance FieldType "snd" (a1, a2, a3, a4, a5, a6) = a2

-- | /Since 0.4.0.0/
type instance UpdateType "snd" (a1, a2, a3, a4, a5, a6) a2' =
    (a1, a2', a3, a4, a5, a6)

-- | /Since 0.4.0.0/
type instance FieldType "thd" (a1, a2, a3, a4, a5, a6) = a3

-- | /Since 0.4.0.0/
type instance UpdateType "thd" (a1, a2, a3, a4, a5, a6) a3' =
    (a1, a2, a3', a4, a5, a6)

-- | /Since 0.4.0.0/
type instance FieldType "curry" ((a1, a2, a3, a4, a5, a6) -> r) =
    a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> r

-- | /Since 0.4.0.0/
instance HasField "fst" (a1, a2, a3, a4, a5, a6) a1 where
    getField _proxy (a1, _, _, _, _, _) = a1

-- | /Since 0.4.0.0/
instance HasField "snd" (a1, a2, a3, a4, a5, a6) a2 where
    getField _proxy (_, a2, _, _, _, _) = a2

-- | /Since 0.4.0.0/
instance HasField "thd" (a1, a2, a3, a4, a5, a6) a3 where
    getField _proxy (_, _, a3, _, _, _) = a3

-- | /Since 0.4.0.0/
instance
    ModifyField "fst" (a1, a2, a3, a4, a5, a6) (a1', a2, a3, a4, a5, a6) a1 a1'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6) = (f a1, a2, a3, a4, a5, a6)
    setField _proxy (_, a2, a3, a4, a5, a6) a1 = (a1, a2, a3, a4, a5, a6)

-- | /Since 0.4.0.0/
instance
    ModifyField "snd" (a1, a2, a3, a4, a5, a6) (a1, a2', a3, a4, a5, a6) a2 a2'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6) = (a1, f a2, a3, a4, a5, a6)
    setField _proxy (a1, _, a3, a4, a5, a6) a2 = (a1, a2, a3, a4, a5, a6)

-- | /Since 0.4.0.0/
instance
    ModifyField "thd" (a1, a2, a3, a4, a5, a6) (a1, a2, a3', a4, a5, a6) a3 a3'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6) = (a1, a2, f a3, a4, a5, a6)
    setField _proxy (a1, a2, _, a4, a5, a6) a3 = (a1, a2, a3, a4, a5, a6)

-- | /Since 0.4.0.0/
instance
    HasField "curry" ((a1, a2, a3, a4, a5, a6) -> r)
        (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> r)
  where
    getField _proxy f a1 a2 a3 a4 a5 a6 = f (a1, a2, a3, a4, a5, a6)

-- }}} Instances -- Tuples -- 6-tuple -----------------------------------------

-- {{{ Instances -- Tuples -- 7-tuple -----------------------------------------

-- | /Since 0.4.0.0/
type instance FieldType "fst" (a1, a2, a3, a4, a5, a6, a7) = a1

-- | /Since 0.4.0.0/
type instance UpdateType "fst" (a1, a2, a3, a4, a5, a6, a7) a1' =
    (a1', a2, a3, a4, a5, a6, a7)

-- | /Since 0.4.0.0/
type instance FieldType "snd" (a1, a2, a3, a4, a5, a6, a7) = a2

-- | /Since 0.4.0.0/
type instance UpdateType "snd" (a1, a2, a3, a4, a5, a6, a7) a2' =
    (a1, a2', a3, a4, a5, a6, a7)

-- | /Since 0.4.0.0/
type instance FieldType "thd" (a1, a2, a3, a4, a5, a6, a7) = a3

-- | /Since 0.4.0.0/
type instance UpdateType "thd" (a1, a2, a3, a4, a5, a6, a7) a3' =
    (a1, a2, a3', a4, a5, a6, a7)

-- | /Since 0.4.0.0/
type instance FieldType "curry" ((a1, a2, a3, a4, a5, a6, a7) -> r) =
    a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> r

-- | /Since 0.4.0.0/
instance HasField "fst" (a1, a2, a3, a4, a5, a6, a7) a1 where
    getField _proxy (a1, _, _, _, _, _, _) = a1

-- | /Since 0.4.0.0/
instance HasField "snd" (a1, a2, a3, a4, a5, a6, a7) a2 where
    getField _proxy (_, a2, _, _, _, _, _) = a2

-- | /Since 0.4.0.0/
instance HasField "thd" (a1, a2, a3, a4, a5, a6, a7) a3 where
    getField _proxy (_, _, a3, _, _, _, _) = a3

-- | /Since 0.4.0.0/
instance
    ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7)
        (a1', a2, a3, a4, a5, a6, a7) a1 a1'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7) =
        (f a1, a2, a3, a4, a5, a6, a7)
    setField _proxy (_, a2, a3, a4, a5, a6, a7) a1 =
        (a1, a2, a3, a4, a5, a6, a7)

-- | /Since 0.4.0.0/
instance
    ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7)
        (a1, a2', a3, a4, a5, a6, a7) a2 a2'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7) =
        (a1, f a2, a3, a4, a5, a6, a7)
    setField _proxy (a1, _, a3, a4, a5, a6, a7) a2 =
        (a1, a2, a3, a4, a5, a6, a7)

-- | /Since 0.4.0.0/
instance
    ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7)
        (a1, a2, a3', a4, a5, a6, a7) a3 a3'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7) =
        (a1, a2, f a3, a4, a5, a6, a7)
    setField _proxy (a1, a2, _, a4, a5, a6, a7) a3 =
        (a1, a2, a3, a4, a5, a6, a7)

-- | /Since 0.4.0.0/
instance
    HasField "curry" ((a1, a2, a3, a4, a5, a6, a7) -> r)
        (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> r)
  where
    getField _proxy f a1 a2 a3 a4 a5 a6 a7 = f (a1, a2, a3, a4, a5, a6, a7)

-- }}} Instances -- Tuples -- 7-tuple -----------------------------------------

-- {{{ Instances -- Tuples -- 8-tuple -----------------------------------------

-- | /Since 0.4.0.0/
type instance FieldType "fst" (a1, a2, a3, a4, a5, a6, a7, a8) = a1

-- | /Since 0.4.0.0/
type instance UpdateType "fst" (a1, a2, a3, a4, a5, a6, a7, a8) a1' =
    (a1', a2, a3, a4, a5, a6, a7, a8)

-- | /Since 0.4.0.0/
type instance FieldType "snd" (a1, a2, a3, a4, a5, a6, a7, a8) = a2

-- | /Since 0.4.0.0/
type instance UpdateType "snd" (a1, a2, a3, a4, a5, a6, a7, a8) a2' =
    (a1, a2', a3, a4, a5, a6, a7, a8)

-- | /Since 0.4.0.0/
type instance FieldType "thd" (a1, a2, a3, a4, a5, a6, a7, a8) = a3

-- | /Since 0.4.0.0/
type instance UpdateType "thd" (a1, a2, a3, a4, a5, a6, a7, a8) a3' =
    (a1, a2, a3', a4, a5, a6, a7, a8)

-- | /Since 0.4.0.0/
type instance FieldType "curry" ((a1, a2, a3, a4, a5, a6, a7, a8) -> r) =
    a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> r

-- | /Since 0.4.0.0/
instance HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8) a1 where
    getField _proxy (a1, _, _, _, _, _, _, _) = a1

-- | /Since 0.4.0.0/
instance HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8) a2 where
    getField _proxy (_, a2, _, _, _, _, _, _) = a2

-- | /Since 0.4.0.0/
instance HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8) a3 where
    getField _proxy (_, _, a3, _, _, _, _, _) = a3

-- | /Since 0.4.0.0/
instance
    ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8)
        (a1', a2, a3, a4, a5, a6, a7, a8) a1 a1'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8) =
        (f a1, a2, a3, a4, a5, a6, a7, a8)
    setField _proxy (_, a2, a3, a4, a5, a6, a7, a8) a1 =
        (a1, a2, a3, a4, a5, a6, a7, a8)

-- | /Since 0.4.0.0/
instance
    ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8)
        (a1, a2', a3, a4, a5, a6, a7, a8) a2 a2'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8) =
        (a1, f a2, a3, a4, a5, a6, a7, a8)
    setField _proxy (a1, _, a3, a4, a5, a6, a7, a8) a2 =
        (a1, a2, a3, a4, a5, a6, a7, a8)

-- | /Since 0.4.0.0/
instance
    ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8)
        (a1, a2, a3', a4, a5, a6, a7, a8) a3 a3'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8) =
        (a1, a2, f a3, a4, a5, a6, a7, a8)
    setField _proxy (a1, a2, _, a4, a5, a6, a7, a8) a3 =
        (a1, a2, a3, a4, a5, a6, a7, a8)

-- | /Since 0.4.0.0/
instance
    HasField "curry" ((a1, a2, a3, a4, a5, a6, a7, a8) -> r)
        (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> r)
  where
    getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 =
        f (a1, a2, a3, a4, a5, a6, a7, a8)

-- }}} Instances -- Tuples -- 8-tuple -----------------------------------------

-- {{{ Instances -- Tuples -- 9-tuple -----------------------------------------

-- | /Since 0.4.0.0/
type instance FieldType "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9) = a1

-- | /Since 0.4.0.0/
type instance UpdateType "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9) a1' =
    (a1', a2, a3, a4, a5, a6, a7, a8, a9)

-- | /Since 0.4.0.0/
type instance FieldType "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9) = a2

-- | /Since 0.4.0.0/
type instance UpdateType "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9) a2' =
    (a1, a2', a3, a4, a5, a6, a7, a8, a9)

-- | /Since 0.4.0.0/
type instance FieldType "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9) = a3

-- | /Since 0.4.0.0/
type instance UpdateType "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9) a3' =
    (a1, a2, a3', a4, a5, a6, a7, a8, a9)

-- | /Since 0.4.0.0/
type instance FieldType "curry" ((a1, a2, a3, a4, a5, a6, a7, a8, a9) -> r) =
    a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> r

-- | /Since 0.4.0.0/
instance HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9) a1 where
    getField _proxy (a1, _, _, _, _, _, _, _, _) = a1

-- | /Since 0.4.0.0/
instance HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9) a2 where
    getField _proxy (_, a2, _, _, _, _, _, _, _) = a2

-- | /Since 0.4.0.0/
instance HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9) a3 where
    getField _proxy (_, _, a3, _, _, _, _, _, _) = a3

-- | /Since 0.4.0.0/
instance
    ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9)
        (a1', a2, a3, a4, a5, a6, a7, a8, a9) a1 a1'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9) =
        (f a1, a2, a3, a4, a5, a6, a7, a8, a9)
    setField _proxy (_, a2, a3, a4, a5, a6, a7, a8, a9) a1 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9)

-- | /Since 0.4.0.0/
instance
    ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9)
        (a1, a2', a3, a4, a5, a6, a7, a8, a9) a2 a2'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9) =
        (a1, f a2, a3, a4, a5, a6, a7, a8, a9)
    setField _proxy (a1, _, a3, a4, a5, a6, a7, a8, a9) a2 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9)

-- | /Since 0.4.0.0/
instance
    ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9)
        (a1, a2, a3', a4, a5, a6, a7, a8, a9) a3 a3'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9) =
        (a1, a2, f a3, a4, a5, a6, a7, a8, a9)
    setField _proxy (a1, a2, _, a4, a5, a6, a7, a8, a9) a3 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9)

-- | /Since 0.4.0.0/
instance
    HasField "curry" ((a1, a2, a3, a4, a5, a6, a7, a8, a9) -> r)
        (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> r)
  where
    getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 =
        f (a1, a2, a3, a4, a5, a6, a7, a8, a9)

-- }}} Instances -- Tuples -- 9-tuple -----------------------------------------

-- {{{ Instances -- Tuples -- 10-tuple ----------------------------------------

-- | /Since 0.4.0.0/
type instance FieldType "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = a1

-- | /Since 0.4.0.0/
type instance UpdateType "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) a1' =
    (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10)

-- | /Since 0.4.0.0/
type instance FieldType "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = a2

-- | /Since 0.4.0.0/
type instance UpdateType "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) a2' =
    (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10)

-- | /Since 0.4.0.0/
type instance FieldType "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = a3

-- | /Since 0.4.0.0/
type instance UpdateType "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) a3' =
    (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10)

-- | /Since 0.4.0.0/
type instance FieldType "curry"
    ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) -> r) =
        a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> r

-- | /Since 0.4.0.0/
instance HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) a1 where
    getField _proxy (a1, _, _, _, _, _, _, _, _, _) = a1

-- | /Since 0.4.0.0/
instance HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) a2 where
    getField _proxy (_, a2, _, _, _, _, _, _, _, _) = a2

-- | /Since 0.4.0.0/
instance HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) a3 where
    getField _proxy (_, _, a3, _, _, _, _, _, _, _) = a3

-- | /Since 0.4.0.0/
instance
    ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
        (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10) a1 a1'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) =
        (f a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
    setField _proxy (_, a2, a3, a4, a5, a6, a7, a8, a9, a10) a1 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)

-- | /Since 0.4.0.0/
instance
    ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
        (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10) a2 a2'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) =
        (a1, f a2, a3, a4, a5, a6, a7, a8, a9, a10)
    setField _proxy (a1, _, a3, a4, a5, a6, a7, a8, a9, a10) a2 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)

-- | /Since 0.4.0.0/
instance
    ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
        (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10) a3 a3'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) =
        (a1, a2, f a3, a4, a5, a6, a7, a8, a9, a10)
    setField _proxy (a1, a2, _, a4, a5, a6, a7, a8, a9, a10) a3 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)

-- | /Since 0.4.0.0/
instance
    HasField "curry" ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) -> r)
        (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> r)
  where
    getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 =
        f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)

-- }}} Instances -- Tuples -- 10-tuple ----------------------------------------

-- {{{ Instances -- Tuples -- 11-tuple ----------------------------------------

-- | /Since 0.4.2.0/
type instance FieldType "fst"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) = a1

-- | /Since 0.4.2.0/
type instance UpdateType "fst"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a1' =
        (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)

-- | /Since 0.4.2.0/
type instance FieldType "snd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) = a2

-- | /Since 0.4.2.0/
type instance UpdateType "snd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a2' =
        (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11)

-- | /Since 0.4.2.0/
type instance FieldType "thd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) = a3

-- | /Since 0.4.2.0/
type instance UpdateType "thd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a3' =
        (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11)

-- | /Since 0.4.2.0/
type instance FieldType "curry"
    ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) -> r) =
        a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> r

-- | /Since 0.4.2.0/
instance HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a1 where
    getField _proxy (a1, _, _, _, _, _, _, _, _, _, _) = a1

-- | /Since 0.4.2.0/
instance HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a2 where
    getField _proxy (_, a2, _, _, _, _, _, _, _, _, _) = a2

-- | /Since 0.4.2.0/
instance HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a3 where
    getField _proxy (_, _, a3, _, _, _, _, _, _, _, _) = a3

-- | /Since 0.4.2.0/
instance
    ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)
        (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a1 a1'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) =
        (f a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)
    setField _proxy (_, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) a1 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)

-- | /Since 0.4.2.0/
instance
    ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)
        (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11) a2 a2'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) =
        (a1, f a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)
    setField _proxy (a1, _, a3, a4, a5, a6, a7, a8, a9, a10, a11) a2 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)

-- | /Since 0.4.2.0/
instance
    ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)
        (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11) a3 a3'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) =
        (a1, a2, f a3, a4, a5, a6, a7, a8, a9, a10, a11)
    setField _proxy (a1, a2, _, a4, a5, a6, a7, a8, a9, a10, a11) a3 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)

-- | /Since 0.4.2.0/
instance
    HasField "curry" ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) -> r)
        (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> r)
  where
    getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 =
        f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)

-- }}} Instances -- Tuples -- 11-tuple ----------------------------------------

-- {{{ Instances -- Tuples -- 12-tuple ----------------------------------------

-- | /Since 0.4.2.0/
type instance FieldType "fst"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) = a1

-- | /Since 0.4.2.0/
type instance UpdateType "fst"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a1' =
        (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)

-- | /Since 0.4.2.0/
type instance FieldType "snd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) = a2

-- | /Since 0.4.2.0/
type instance UpdateType "snd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a2' =
        (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)

-- | /Since 0.4.2.0/
type instance FieldType "thd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) = a3

-- | /Since 0.4.2.0/
type instance UpdateType "thd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a3' =
        (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12)

-- | /Since 0.4.2.0/
type instance FieldType "curry"
    ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) -> r) =
        a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> a12
        -> r

-- | /Since 0.4.2.0/
instance HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a1
  where
    getField _proxy (a1, _, _, _, _, _, _, _, _, _, _, _) = a1

-- | /Since 0.4.2.0/
instance HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a2
  where
    getField _proxy (_, a2, _, _, _, _, _, _, _, _, _, _) = a2

-- | /Since 0.4.2.0/
instance HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a3
  where
    getField _proxy (_, _, a3, _, _, _, _, _, _, _, _, _) = a3

-- | /Since 0.4.2.0/
instance
    ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
        (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a1 a1'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) =
        (f a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
    setField _proxy (_, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a1 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)

-- | /Since 0.4.2.0/
instance
    ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
        (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a2 a2'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) =
        (a1, f a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
    setField _proxy (a1, _, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) a2 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)

-- | /Since 0.4.2.0/
instance
    ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
        (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12) a3 a3'
  where
    modifyField _proxy f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) =
        (a1, a2, f a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
    setField _proxy (a1, a2, _, a4, a5, a6, a7, a8, a9, a10, a11, a12) a3 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)

-- | /Since 0.4.2.0/
instance
    HasField "curry" ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) -> r)
        ( a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11
        -> a12 -> r
        )
  where
    getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 =
        f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)

-- }}} Instances -- Tuples -- 12-tuple ----------------------------------------

-- {{{ Instances -- Tuples -- 13-tuple ----------------------------------------

-- | /Since 0.4.2.0/
type instance FieldType "fst"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) = a1

-- | /Since 0.4.2.0/
type instance UpdateType "fst"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a1' =
        (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)

-- | /Since 0.4.2.0/
type instance FieldType "snd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) = a2

-- | /Since 0.4.2.0/
type instance UpdateType "snd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a2' =
        (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)

-- | /Since 0.4.2.0/
type instance FieldType "thd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) = a3

-- | /Since 0.4.2.0/
type instance UpdateType "thd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a3' =
        (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)

-- | /Since 0.4.2.0/
type instance FieldType "curry"
    ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) -> r) =
        a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> a12
        -> a13 -> r

-- | /Since 0.4.2.0/
instance
    HasField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a1
  where
    getField _proxy (a1, _, _, _, _, _, _, _, _, _, _, _, _) = a1

-- | /Since 0.4.2.0/
instance
    HasField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a2
  where
    getField _proxy (_, a2, _, _, _, _, _, _, _, _, _, _, _) = a2

-- | /Since 0.4.2.0/
instance
    HasField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a3
  where
    getField _proxy (_, _, a3, _, _, _, _, _, _, _, _, _, _) = a3

-- | /Since 0.4.2.0/
instance
    ModifyField "fst" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)
        (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a1 a1'
  where
    modifyField _proxy f
      (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) =
        (f a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)
    setField _proxy
      (_, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a1 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)

-- | /Since 0.4.2.0/
instance
    ModifyField "snd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)
        (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a2 a2'
  where
    modifyField _proxy f
      (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) =
        (a1, f a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)
    setField _proxy
      (a1, _, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a2 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)

-- | /Since 0.4.2.0/
instance
    ModifyField "thd" (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)
        (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a3 a3'
  where
    modifyField _proxy f
      (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) =
        (a1, a2, f a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)
    setField _proxy
      (a1, a2, _, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) a3 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)

-- | /Since 0.4.2.0/
instance
    HasField "curry"
        ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) -> r)
        ( a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11
        -> a12 -> a13 -> r
        )
  where
    getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 =
        f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)

-- }}} Instances -- Tuples -- 13-tuple ----------------------------------------

-- {{{ Instances -- Tuples -- 14-tuple ----------------------------------------

-- | /Since 0.4.2.0/
type instance FieldType "fst"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) = a1

-- | /Since 0.4.2.0/
type instance UpdateType "fst"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a1' =
        (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)

-- | /Since 0.4.2.0/
type instance FieldType "snd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) = a2

-- | /Since 0.4.2.0/
type instance UpdateType "snd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a2' =
        (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)

-- | /Since 0.4.2.0/
type instance FieldType "thd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) = a3

-- | /Since 0.4.2.0/
type instance UpdateType "thd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a3' =
        (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)

-- | /Since 0.4.2.0/
type instance FieldType "curry"
    ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) -> r) =
        a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> a12
        -> a13 -> a14 -> r

-- | /Since 0.4.2.0/
instance
    HasField "fst"
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a1
  where
    getField _proxy (a1, _, _, _, _, _, _, _, _, _, _, _, _, _) = a1

-- | /Since 0.4.2.0/
instance
    HasField "snd"
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a2
  where
    getField _proxy (_, a2, _, _, _, _, _, _, _, _, _, _, _, _) = a2

-- | /Since 0.4.2.0/
instance
    HasField "thd"
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a3
  where
    getField _proxy (_, _, a3, _, _, _, _, _, _, _, _, _, _, _) = a3

-- | /Since 0.4.2.0/
instance
    ModifyField "fst"
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)
        (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a1 a1'
  where
    modifyField _proxy f
      (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) =
        (f a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)
    setField _proxy
      (_, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a1 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)

-- | /Since 0.4.2.0/
instance
    ModifyField "snd"
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)
        (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a2 a2'
  where
    modifyField _proxy f
      (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) =
        (a1, f a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)
    setField _proxy
      (a1, _, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a2 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)

-- | /Since 0.4.2.0/
instance
    ModifyField "thd"
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)
        (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a3 a3'
  where
    modifyField _proxy f
      (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) =
        (a1, a2, f a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)
    setField _proxy
      (a1, a2, _, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) a3 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)

-- | /Since 0.4.2.0/
instance
    HasField "curry"
        ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) -> r)
        ( a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11
        -> a12 -> a13 -> a14 -> r
        )
  where
    getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 =
        f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)

-- }}} Instances -- Tuples -- 14-tuple ----------------------------------------

-- {{{ Instances -- Tuples -- 15-tuple ----------------------------------------

-- | /Since 0.4.2.0/
type instance FieldType "fst"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) = a1

-- | /Since 0.4.2.0/
type instance UpdateType "fst"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a1' =
        (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)

-- | /Since 0.4.2.0/
type instance FieldType "snd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) = a2

-- | /Since 0.4.2.0/
type instance UpdateType "snd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a2' =
        (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)

-- | /Since 0.4.2.0/
type instance FieldType "thd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) = a3

-- | /Since 0.4.2.0/
type instance UpdateType "thd"
    (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a3' =
        (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)

-- | /Since 0.4.2.0/
type instance FieldType "curry"
    ((a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) -> r) =
        a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11 -> a12
        -> a13 -> a14 -> a15 -> r

-- | /Since 0.4.2.0/
instance
    HasField "fst"
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a1
  where
    getField _proxy (a1, _, _, _, _, _, _, _, _, _, _, _, _, _, _) = a1

-- | /Since 0.4.2.0/
instance
    HasField "snd"
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a2
  where
    getField _proxy (_, a2, _, _, _, _, _, _, _, _, _, _, _, _, _) = a2

-- | /Since 0.4.2.0/
instance
    HasField "thd"
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a3
  where
    getField _proxy (_, _, a3, _, _, _, _, _, _, _, _, _, _, _, _) = a3

-- | /Since 0.4.2.0/
instance
    ModifyField "fst"
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
        (a1', a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
        a1 a1'
  where
    modifyField _proxy f
      (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) =
        (f a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
    setField _proxy
      (_, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a1 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)

-- | /Since 0.4.2.0/
instance
    ModifyField "snd"
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
        (a1, a2', a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
        a2 a2'
  where
    modifyField _proxy f
      (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) =
        (a1, f a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
    setField _proxy
      (a1, _, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a2 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)

-- | /Since 0.4.2.0/
instance
    ModifyField "thd"
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
        (a1, a2, a3', a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
        a3 a3'
  where
    modifyField _proxy f
      (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) =
        (a1, a2, f a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
    setField _proxy
      (a1, a2, _, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) a3 =
        (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)

-- | /Since 0.4.2.0/
instance
    HasField "curry"
        ( (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
        -> r
        )
        ( a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> a9 -> a10 -> a11
        -> a12 -> a13 -> a14 -> a15 -> r
        )
  where
    getField _proxy f a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 =
        f (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)

-- }}} Instances -- Tuples -- 15-tuple ----------------------------------------

-- }}} Instances -- Tuples ----------------------------------------------------

-- {{{ Instances -- Lists -----------------------------------------------------

-- | /Since 0.4.0.0/
type instance FieldType "head" [a] = Maybe a

-- | /Since 0.4.0.0/
type instance UpdateType "head" [a] (Maybe a) = [a]

-- |
-- >>> #head []
-- Nothing
--
-- >>> #head [1, 2, 3]
-- Just 1
--
-- /Since 0.4.0.0/
instance HasField "head" [a] (Maybe a) where
    getField _proxy []      = Nothing
    getField _proxy (a : _) = Just a

-- |
-- >>> set' #head [] Nothing :: [Int]
-- []
--
-- >>> set' #head [] (Just 1)
-- [1]
--
-- >>> set' #head [1, 2, 3] Nothing
-- [2, 3]
--
-- >>> set' #head [1, 2, 3] (Just 4)
-- [4, 2, 3]
--
-- /Since 0.4.0.0/
instance ModifyField "head" [a] [a] (Maybe a) (Maybe a) where
    modifyField _proxy f = \case
        [] -> case f Nothing of
            Nothing -> []
            Just a -> [a]
        a : as -> case f (Just a) of
            Nothing -> as
            Just a' -> a' : as

    setField _proxy = \case
        [] -> \case
            Nothing -> []
            Just a -> [a]
        _ : as -> \case
            Nothing -> as
            Just a -> a : as

-- | /Since 0.4.0.0/
type instance FieldType "tail" [a] = Maybe [a]

-- | /Since 0.4.0.0/
type instance UpdateType "tail" [a] (Maybe [a]) = [a]

-- |
-- >>> #tail []
-- Nothing
--
-- >>> #tail [1, 2, 3]
-- Just [2, 3]
--
-- /Since 0.4.0.0/
instance HasField "tail" [a] (Maybe [a]) where
    getField _proxy []       = Nothing
    getField _proxy (_ : as) = Just as

-- |
-- >>> set' #tail [] Nothing :: [Int]
-- []
--
-- >>> set' #tail [] (Just [2, 3])
-- [2, 3]
--
-- >>> set' #tail [1, 2, 3] Nothing
-- [1]
--
-- >>> set' #tail [1, 2, 3] (Just [4, 5, 6])
-- [1, 4, 5, 6]
--
-- /Since 0.4.0.0/
instance ModifyField "tail" [a] [a] (Maybe [a]) (Maybe [a]) where
    modifyField _proxy f = \case
        [] -> case f Nothing of
            Nothing -> []
            Just as -> as
        a : as -> case f (Just as) of
            Nothing -> [a]
            Just as' -> a : as'

    setField _proxy = \case
        [] -> \case
            Nothing -> []
            Just as -> as
        a : _ -> \case
            Nothing -> [a]
            Just as -> a : as

-- }}} Instances -- Lists -----------------------------------------------------

#ifdef HAVE_NON_EMPTY_LIST
-- {{{ Instances -- Non-empty Lists -------------------------------------------

-- | /Since 0.4.2.0/
type instance FieldType "head" (NonEmpty a) = a

-- | /Since 0.4.2.0/
type instance UpdateType "head" (NonEmpty a) a = NonEmpty a

-- |
-- >>> #head 1 :| []
-- 1
--
-- >>> #head (1 :| [2, 3])
-- 1
--
-- /Since 0.4.2.0/
instance HasField "head" (NonEmpty a) a where
    getField _proxy (a :| _) = a

-- |
-- >>> set' #head [1, 2, 3] 4
-- [4, 2, 3]
--
-- /Since 0.4.2.0/
instance ModifyField "head" (NonEmpty a) (NonEmpty a) a a where
    modifyField _proxy f (a :| as) = f a :| as
    setField _proxy (_ :| as) a = a :| as

-- | /Since 0.4.2.0/
type instance FieldType "tail" (NonEmpty a) = [a]

-- | /Since 0.4.2.0/
type instance UpdateType "tail" (NonEmpty a) [a] = NonEmpty a

-- |
-- >>> #tail (1 :| [])
-- []
--
-- >>> #tail (1 :| [2, 3])
-- [2, 3]
--
-- /Since 0.4.2.0/
instance HasField "tail" (NonEmpty a) [a] where
    getField _proxy (_ :| as) = as

-- |
-- >>> set' #tail (1 :| []) []
-- (1 :| [])
--
-- >>> set' #tail (1 :| []) [2, 3]
-- 1 :| [2, 3]
--
-- >>> set' #tail (1 :| [2, 3]) []
-- 1 :| []
--
-- >>> set' #tail (1 :| [2, 3]) [4, 5, 6]
-- 1 :| [4, 5, 6]
--
-- /Since 0.4.2.0/
instance ModifyField "tail" (NonEmpty a) (NonEmpty a) [a] [a] where
    modifyField _proxy f (a :| as) = a :| f as
    setField _proxy (a :| _) as = a :| as

-- }}} Instances -- Non-empty Lists -------------------------------------------
#endif
    -- HAVE_NON_EMPTY_LIST

-- }}} Instances --------------------------------------------------------------

-- $usageExamples
--
-- @
-- -- Basic set of language extensions required when defining instances for
-- -- classes and type families from "Data.OverloadedRecords".
-- {-\# LANGUAGE DataKinds \#-}
-- {-\# LANGUAGE FlexibleInstances \#-}
-- {-\# LANGUAGE MultiParamTypeClasses \#-}
-- {-\# LANGUAGE TemplateHaskell \#-}
-- {-\# LANGUAGE TypeFamilies \#-}
--
-- -- Following language extensions are required by code like this:
--
-- {-\# LANGUAGE ConstraintKinds \#-}
--     -- Codomain of type family 'R' is a 'Constraint' kind.
--
-- {-\# LANGUAGE FlexibleContexts \#-}
--     -- Required in example when field type (second argument of ':::') is a
--     -- specific type instead of a polymorphic type.
--
-- {-\# LANGUAGE TypeOperators \#-}
--     -- Required due to usage of ':::' type alias.
--
-- -- Following language extensions are available only in GHC >=8:
--
-- {-\# LANGUAGE OverloadedLabels \#-}
--     -- Enables #label syntactic sugar.
--
-- module Example
--   where
--
-- import Data.Default (Default(def))
--     -- Provided by one of these packages:
--     --
--     -- * <https://hackage.haskell.org/package/data-default data-default>
--     -- * <https://hackage.haskell.org/package/data-default data-default-extra>
--
-- import "Data.OverloadedRecords"
-- import "Data.OverloadedRecords.TH" ('Data.OverloadedRecords.TH.overloadedRecord')
--
--
-- data V3 a = V3
--     { v3x :: !a
--     , v3y :: !a
--     , v3z :: !a
--     }
--   deriving Show
--
-- -- Following line derives instances for various type classes and type
-- -- families that are provided by the overloaded-records library.
-- --
-- -- However with def (default settings) this is done only for fields that
-- -- start with type name, data constructor name, or underscore. Prefix is
-- -- stripped. In example \"v3x\" is transformed in to \"x\" and so would be
-- -- \"_x\".
-- 'Data.OverloadedRecords.TH.overloadedRecord' def ''V3
--
-- data V4 a = V4
--     { v4x :: !a
--     , v4y :: !a
--     , v4z :: !a
--     , v4t :: !a
--     }
--   deriving Show
--
-- 'Data.OverloadedRecords.TH.overloadedRecord' def ''V4
--
-- zeroV3
--     :: (Num a, 'R' '[\"x\" ':::' a, \"y\" ':::' a, \"z\" ':::' a] r)
--     => r -> r
-- zeroV3 = 'set'' \#x 0 . 'set'' \#y 0 . 'set'' \#z 0
-- @
--
-- The following type signatures for @zeroV3@ are equivalent:
--
-- @
-- zeroV3
--     :: (Num a, 'R' '[\"x\" ':::' a, \"y\" ':::' a, \"z\" ':::' a] r)
--     => r -> r
-- @
--
-- @
-- zeroV3
--     ::  ( Num a
--         , 'ModifyField'' \"x\" r a
--         , 'ModifyField'' \"y\" r a
--         , 'ModifyField'' \"z\" r a
--         )
--     => r -> r
-- @
--
-- One of the biggest features of /Overloaded Records/ is the possibility to
-- define functions that do not depend on concrete data types, but on the
-- \"fields\" they provide. In example function @zeroV3@ can be applied to
-- anything that has fields @\"x\"@, @\"y\"@, and @\"z\"@ that reference values
-- of some @Num@ type:
--
-- >>> zeroV3 (V3 1 1 1 :: V3 Int)
-- V3 {_x = 0, _y = 0, _z = 0}
--
-- >>> zeroV3 (V4 1 1 1 1 :: V4 Int)
-- V4 {_x = 0, _y = 0, _z = 0, _t = 1}
--
-- Function @zeroV3@ can be also defined using operators from
-- <https://hackage.haskell.org/package/lens lens> library:
--
-- @
-- import Control.Lens ((.~), simple)
--
-- zeroV3
--     :: (Num a, 'R' '[\"x\" ':::' a, \"y\" ':::' a, \"z\" ':::' a] r)
--     => r -> r
-- zeroV3 r = r
--     & \#x . simple .~ 0
--     & \#y . simple .~ 0
--     & \#z . simple .~ 0
-- @
--
-- However, following function would fail to compile:
--
-- @
-- incV3
--     :: (Num a, 'R' '[\"x\" ':::' a, \"y\" ':::' a, \"z\" ':::' a] r)
--     => r -> r
-- incV3 r = r
--     & \#x . simple .~ \#x r + 1
--     & \#y . simple .~ \#y r + 1
--     & \#z . simple .~ \#z r + 1
-- @
--
-- The problem is that we have two 'IsLabel' instances at play. One is for a
-- lens and the other one is for getter. Unfortunatelly these two instances are
-- mutually exclusive in case of polymorphic value. There are multiple
-- solutions to this. Use lenses all the time, e.g. in general by using @^.@
-- for getting the value, or in this case by using @+~@ operator for
-- incrementing. Example of using @+~@:
--
-- @
-- import Control.Lens ((.~), (+~), simple)
--
-- incV3
--     :: (Num a, 'R' '[\"x\" ':::' a, \"y\" ':::' a, \"z\" ':::' a] r)
--     => r -> r
-- incV3 r = r
--     & \#x . simple +~ 1
--     & \#y . simple +~ 1
--     & \#z . simple +~ 1
-- @