{-# LANGUAGE CPP, Trustworthy #-}
{-# LANGUAGE NoImplicitPrelude, MagicHash, StandaloneDeriving, BangPatterns,
             KindSignatures, DataKinds, ConstraintKinds,
              MultiParamTypeClasses, FunctionalDependencies #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
  -- ip :: IP x a => a  is strictly speaking ambiguous, but IP is magic
{-# LANGUAGE UndecidableSuperClasses #-}
  -- Because of the type-variable superclasses for tuples

{-# OPTIONS_GHC -Wno-unused-imports #-}
-- -Wno-unused-imports needed for the GHC.Tuple import below. Sigh.

{-# OPTIONS_GHC -Wno-unused-top-binds #-}
-- -Wno-unused-top-binds is there (I hope) to stop Haddock complaining
-- about the constraint tuples being defined but not used

{-# OPTIONS_HADDOCK not-home #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  GHC.Classes
-- Copyright   :  (c) The University of Glasgow, 1992-2002
-- License     :  see libraries/base/LICENSE
--
-- Maintainer  :  cvs-ghc@haskell.org
-- Stability   :  internal
-- Portability :  non-portable (GHC extensions)
--
-- Basic classes.
--
-----------------------------------------------------------------------------

module GHC.Classes(
    -- * Implicit paramaters
    IP(..),

    -- * Equality and ordering
    Eq(..),
    Ord(..),
    -- ** Monomorphic equality operators
    -- $matching_overloaded_methods_in_rules
    eqInt, neInt,
    eqWord, neWord,
    eqChar, neChar,
    eqFloat, eqDouble,
    -- ** Monomorphic comparison operators
    gtInt, geInt, leInt, ltInt, compareInt, compareInt#,
    gtWord, geWord, leWord, ltWord, compareWord, compareWord#,

    -- * Functions over Bool
    (&&), (||), not,

    -- * Integer arithmetic
    divInt#, divInt8#, divInt16#, divInt32#,
    modInt#, modInt8#, modInt16#, modInt32#,
    divModInt#, divModInt8#, divModInt16#, divModInt32#
 ) where

-- GHC.Magic is used in some derived instances
import GHC.Magic ()
import GHC.Prim
import GHC.Tuple
import GHC.CString (unpackCString#)
import GHC.Types

#include "MachDeps.h"

infix  4  ==, /=, <, <=, >=, >
infixr 3  &&
infixr 2  ||

default ()              -- Double isn't available yet

-- | The syntax @?x :: a@ is desugared into @IP "x" a@
-- IP is declared very early, so that libraries can take
-- advantage of the implicit-call-stack feature
class IP (x :: Symbol) a | x -> a where
  ip :: a

{- $matching_overloaded_methods_in_rules

Matching on class methods (e.g. @(==)@) in rewrite rules tends to be a bit
fragile. For instance, consider this motivating example from the @bytestring@
library,

@
break :: (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
breakByte :: Word8 -> ByteString -> (ByteString, ByteString)
\{\-\# RULES "break -> breakByte" forall a. break (== x) = breakByte x \#\-\}
@

Here we have two functions, with @breakByte@ providing an optimized
implementation of @break@ where the predicate is merely testing for equality
with a known @Word8@. As written, however, this rule will be quite fragile as
the @(==)@ class operation rule may rewrite the predicate before our @break@
rule has a chance to fire.

For this reason, most of the primitive types in @base@ have 'Eq' and 'Ord'
instances defined in terms of helper functions with inlinings delayed to phase
1. For instance, @Word8@\'s @Eq@ instance looks like,

@
instance Eq Word8 where
    (==) = eqWord8
    (/=) = neWord8

eqWord8, neWord8 :: Word8 -> Word8 -> Bool
eqWord8 (W8# x) (W8# y) = ...
neWord8 (W8# x) (W8# y) = ...
\{\-\# INLINE [1] eqWord8 \#\-\}
\{\-\# INLINE [1] neWord8 \#\-\}
@

This allows us to save our @break@ rule above by rewriting it to instead match
against @eqWord8@,

@
\{\-\# RULES "break -> breakByte" forall a. break (`eqWord8` x) = breakByte x \#\-\}
@

Currently this is only done for @('==')@, @('/=')@, @('<')@, @('<=')@, @('>')@,
and @('>=')@ for the types in "GHC.Word" and "GHC.Int".
-}

-- | The 'Eq' class defines equality ('==') and inequality ('/=').
-- All the basic datatypes exported by the "Prelude" are instances of 'Eq',
-- and 'Eq' may be derived for any datatype whose constituents are also
-- instances of 'Eq'.
--
-- The Haskell Report defines no laws for 'Eq'. However, instances are
-- encouraged to follow these properties:
--
-- [__Reflexivity__]: @x == x@ = 'True'
-- [__Symmetry__]: @x == y@ = @y == x@
-- [__Transitivity__]: if @x == y && y == z@ = 'True', then @x == z@ = 'True'
-- [__Extensionality__]: if @x == y@ = 'True' and @f@ is a function
-- whose return type is an instance of 'Eq', then @f x == f y@ = 'True'
-- [__Negation__]: @x /= y@ = @not (x == y)@
--
-- Minimal complete definition: either '==' or '/='.
--
class  Eq a  where
    (==), (/=)           :: a -> a -> Bool

    {-# INLINE (/=) #-}
    {-# INLINE (==) #-}
    a
x /= a
y               = Bool -> Bool
not (a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
y)
    a
x == a
y               = Bool -> Bool
not (a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
y)
    {-# MINIMAL (==) | (/=) #-}

deriving instance Eq ()
deriving instance Eq a => Eq (Solo a)
deriving instance (Eq  a, Eq  b) => Eq  (a, b)
deriving instance (Eq  a, Eq  b, Eq  c) => Eq  (a, b, c)
deriving instance (Eq  a, Eq  b, Eq  c, Eq  d) => Eq  (a, b, c, d)
deriving instance (Eq  a, Eq  b, Eq  c, Eq  d, Eq  e) => Eq  (a, b, c, d, e)
deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f)
               => Eq (a, b, c, d, e, f)
deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g)
               => Eq (a, b, c, d, e, f, g)
deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
                   Eq h)
               => Eq (a, b, c, d, e, f, g, h)
deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
                   Eq h, Eq i)
               => Eq (a, b, c, d, e, f, g, h, i)
deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
                   Eq h, Eq i, Eq j)
               => Eq (a, b, c, d, e, f, g, h, i, j)
deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
                   Eq h, Eq i, Eq j, Eq k)
               => Eq (a, b, c, d, e, f, g, h, i, j, k)
deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
                   Eq h, Eq i, Eq j, Eq k, Eq l)
               => Eq (a, b, c, d, e, f, g, h, i, j, k, l)
deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
                   Eq h, Eq i, Eq j, Eq k, Eq l, Eq m)
               => Eq (a, b, c, d, e, f, g, h, i, j, k, l, m)
deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
                   Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Eq n)
               => Eq (a, b, c, d, e, f, g, h, i, j, k, l, m, n)
deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
                   Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Eq n, Eq o)
               => Eq (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)

instance (Eq a) => Eq [a] where
    {-# SPECIALISE instance Eq [[Char]] #-}
    {-# SPECIALISE instance Eq [Char] #-}
    {-# SPECIALISE instance Eq [Int] #-}
    []     == :: [a] -> [a] -> Bool
== []     = Bool
True
    (a
x:[a]
xs) == (a
y:[a]
ys) = a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
y Bool -> Bool -> Bool
&& [a]
xs [a] -> [a] -> Bool
forall a. Eq a => a -> a -> Bool
== [a]
ys
    [a]
_xs    == [a]
_ys    = Bool
False

deriving instance Eq Module

instance Eq TrName where
    TrNameS Addr#
a == :: TrName -> TrName -> Bool
== TrNameS Addr#
b = Int# -> Bool
isTrue# (Addr#
a Addr# -> Addr# -> Int#
`eqAddr#` Addr#
b)
    TrName
a == TrName
b = TrName -> [Char]
toString TrName
a [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== TrName -> [Char]
toString TrName
b
      where
        toString :: TrName -> [Char]
toString (TrNameS Addr#
s) = Addr# -> [Char]
unpackCString# Addr#
s
        toString (TrNameD [Char]
s) = [Char]
s

deriving instance Eq Bool
deriving instance Eq Ordering

instance Eq Word where
    == :: Word -> Word -> Bool
(==) = Word -> Word -> Bool
eqWord
    /= :: Word -> Word -> Bool
(/=) = Word -> Word -> Bool
neWord

-- See GHC.Classes#matching_overloaded_methods_in_rules
{-# INLINE [1] eqWord #-}
{-# INLINE [1] neWord #-}
eqWord, neWord :: Word -> Word -> Bool
(W# Word#
x) eqWord :: Word -> Word -> Bool
`eqWord` (W# Word#
y) = Int# -> Bool
isTrue# (Word#
x Word# -> Word# -> Int#
`eqWord#` Word#
y)
(W# Word#
x) neWord :: Word -> Word -> Bool
`neWord` (W# Word#
y) = Int# -> Bool
isTrue# (Word#
x Word# -> Word# -> Int#
`neWord#` Word#
y)

-- See GHC.Classes#matching_overloaded_methods_in_rules
instance Eq Char where
    == :: Char -> Char -> Bool
(==) = Char -> Char -> Bool
eqChar
    /= :: Char -> Char -> Bool
(/=) = Char -> Char -> Bool
neChar

-- See GHC.Classes#matching_overloaded_methods_in_rules
{-# INLINE [1] eqChar #-}
{-# INLINE [1] neChar #-}
eqChar, neChar :: Char -> Char -> Bool
(C# Char#
x) eqChar :: Char -> Char -> Bool
`eqChar` (C# Char#
y) = Int# -> Bool
isTrue# (Char#
x Char# -> Char# -> Int#
`eqChar#` Char#
y)
(C# Char#
x) neChar :: Char -> Char -> Bool
`neChar` (C# Char#
y) = Int# -> Bool
isTrue# (Char#
x Char# -> Char# -> Int#
`neChar#` Char#
y)

-- | Note that due to the presence of @NaN@, `Float`'s 'Eq' instance does not
-- satisfy reflexivity.
--
-- >>> 0/0 == (0/0 :: Float)
-- False
--
-- Also note that `Float`'s 'Eq' instance does not satisfy extensionality:
--
-- >>> 0 == (-0 :: Float)
-- True
-- >>> recip 0 == recip (-0 :: Float)
-- False
instance Eq Float where
    == :: Float -> Float -> Bool
(==) = Float -> Float -> Bool
eqFloat

-- See GHC.Classes#matching_overloaded_methods_in_rules
{-# INLINE [1] eqFloat #-}
eqFloat :: Float -> Float -> Bool
(F# Float#
x) eqFloat :: Float -> Float -> Bool
`eqFloat` (F# Float#
y) = Int# -> Bool
isTrue# (Float#
x Float# -> Float# -> Int#
`eqFloat#` Float#
y)

-- | Note that due to the presence of @NaN@, `Double`'s 'Eq' instance does not
-- satisfy reflexivity.
--
-- >>> 0/0 == (0/0 :: Double)
-- False
--
-- Also note that `Double`'s 'Eq' instance does not satisfy substitutivity:
--
-- >>> 0 == (-0 :: Double)
-- True
-- >>> recip 0 == recip (-0 :: Double)
-- False
instance Eq Double where
    == :: Double -> Double -> Bool
(==) = Double -> Double -> Bool
eqDouble

-- See GHC.Classes#matching_overloaded_methods_in_rules
{-# INLINE [1] eqDouble #-}
eqDouble :: Double -> Double -> Bool
(D# Double#
x) eqDouble :: Double -> Double -> Bool
`eqDouble` (D# Double#
y) = Int# -> Bool
isTrue# (Double#
x Double# -> Double# -> Int#
==## Double#
y)

instance Eq Int where
    == :: Int -> Int -> Bool
(==) = Int -> Int -> Bool
eqInt
    /= :: Int -> Int -> Bool
(/=) = Int -> Int -> Bool
neInt

-- See GHC.Classes#matching_overloaded_methods_in_rules
{-# INLINE [1] eqInt #-}
{-# INLINE [1] neInt #-}
eqInt, neInt :: Int -> Int -> Bool
(I# Int#
x) eqInt :: Int -> Int -> Bool
`eqInt` (I# Int#
y) = Int# -> Bool
isTrue# (Int#
x Int# -> Int# -> Int#
==# Int#
y)
(I# Int#
x) neInt :: Int -> Int -> Bool
`neInt` (I# Int#
y) = Int# -> Bool
isTrue# (Int#
x Int# -> Int# -> Int#
/=# Int#
y)

#if WORD_SIZE_IN_BITS < 64
instance Eq TyCon where
  (==) (TyCon hi1 lo1 _ _ _ _) (TyCon hi2 lo2 _ _ _ _)
       = isTrue# (hi1 `eqWord64#` hi2) && isTrue# (lo1 `eqWord64#` lo2)
instance Ord TyCon where
  compare (TyCon hi1 lo1 _ _ _ _) (TyCon hi2 lo2 _ _ _ _)
    | isTrue# (hi1 `gtWord64#` hi2) = GT
    | isTrue# (hi1 `ltWord64#` hi2) = LT
    | isTrue# (lo1 `gtWord64#` lo2) = GT
    | isTrue# (lo1 `ltWord64#` lo2) = LT
    | True                = EQ
#else
instance Eq TyCon where
  == :: TyCon -> TyCon -> Bool
(==) (TyCon Word#
hi1 Word#
lo1 Module
_ TrName
_ Int#
_ KindRep
_) (TyCon Word#
hi2 Word#
lo2 Module
_ TrName
_ Int#
_ KindRep
_)
       = Int# -> Bool
isTrue# (Word#
hi1 Word# -> Word# -> Int#
`eqWord#` Word#
hi2) Bool -> Bool -> Bool
&& Int# -> Bool
isTrue# (Word#
lo1 Word# -> Word# -> Int#
`eqWord#` Word#
lo2)
instance Ord TyCon where
  compare :: TyCon -> TyCon -> Ordering
compare (TyCon Word#
hi1 Word#
lo1 Module
_ TrName
_ Int#
_ KindRep
_) (TyCon Word#
hi2 Word#
lo2 Module
_ TrName
_ Int#
_ KindRep
_)
    | Int# -> Bool
isTrue# (Word#
hi1 Word# -> Word# -> Int#
`gtWord#` Word#
hi2) = Ordering
GT
    | Int# -> Bool
isTrue# (Word#
hi1 Word# -> Word# -> Int#
`ltWord#` Word#
hi2) = Ordering
LT
    | Int# -> Bool
isTrue# (Word#
lo1 Word# -> Word# -> Int#
`gtWord#` Word#
lo2) = Ordering
GT
    | Int# -> Bool
isTrue# (Word#
lo1 Word# -> Word# -> Int#
`ltWord#` Word#
lo2) = Ordering
LT
    | Bool
True              = Ordering
EQ
#endif


-- | The 'Ord' class is used for totally ordered datatypes.
--
-- Instances of 'Ord' can be derived for any user-defined datatype whose
-- constituent types are in 'Ord'. The declared order of the constructors in
-- the data declaration determines the ordering in derived 'Ord' instances. The
-- 'Ordering' datatype allows a single comparison to determine the precise
-- ordering of two objects.
--
-- 'Ord', as defined by the Haskell report, implements a total order and has the
-- following properties:
--
-- [__Comparability__]: @x <= y || y <= x@ = 'True'
-- [__Transitivity__]: if @x <= y && y <= z@ = 'True', then @x <= z@ = 'True'
-- [__Reflexivity__]: @x <= x@ = 'True'
-- [__Antisymmetry__]: if @x <= y && y <= x@ = 'True', then @x == y@ = 'True'
--
-- The following operator interactions are expected to hold:
--
-- 1. @x >= y@ = @y <= x@
-- 2. @x < y@ = @x <= y && x /= y@
-- 3. @x > y@ = @y < x@
-- 4. @x < y@ = @compare x y == LT@
-- 5. @x > y@ = @compare x y == GT@
-- 6. @x == y@ = @compare x y == EQ@
-- 7. @min x y == if x <= y then x else y@ = 'True'
-- 8. @max x y == if x >= y then x else y@ = 'True'
--
-- Note that (7.) and (8.) do /not/ require 'min' and 'max' to return either of
-- their arguments. The result is merely required to /equal/ one of the
-- arguments in terms of '(==)'.
--
-- Minimal complete definition: either 'compare' or '<='.
-- Using 'compare' can be more efficient for complex types.
--
class  (Eq a) => Ord a  where
    compare              :: a -> a -> Ordering
    (<), (<=), (>), (>=) :: a -> a -> Bool
    max, min             :: a -> a -> a

    compare a
x a
y = if a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
y then Ordering
EQ
                  -- NB: must be '<=' not '<' to validate the
                  -- above claim about the minimal things that
                  -- can be defined for an instance of Ord:
                  else if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
y then Ordering
LT
                  else Ordering
GT

    a
x <  a
y = case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
x a
y of { Ordering
LT -> Bool
True;  Ordering
_ -> Bool
False }
    a
x <= a
y = case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
x a
y of { Ordering
GT -> Bool
False; Ordering
_ -> Bool
True }
    a
x >  a
y = case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
x a
y of { Ordering
GT -> Bool
True;  Ordering
_ -> Bool
False }
    a
x >= a
y = case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
x a
y of { Ordering
LT -> Bool
False; Ordering
_ -> Bool
True }

        -- These two default methods use '<=' rather than 'compare'
        -- because the latter is often more expensive
    max a
x a
y = if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
y then a
y else a
x
    min a
x a
y = if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
y then a
x else a
y
    {-# MINIMAL compare | (<=) #-}

deriving instance Ord ()
deriving instance Ord a => Ord (Solo a)
deriving instance (Ord a, Ord b) => Ord (a, b)
deriving instance (Ord a, Ord b, Ord c) => Ord (a, b, c)
deriving instance (Ord a, Ord b, Ord c, Ord d) => Ord (a, b, c, d)
deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e) => Ord (a, b, c, d, e)
deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f)
               => Ord (a, b, c, d, e, f)
deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g)
               => Ord (a, b, c, d, e, f, g)
deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
                   Ord h)
               => Ord (a, b, c, d, e, f, g, h)
deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
                   Ord h, Ord i)
               => Ord (a, b, c, d, e, f, g, h, i)
deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
                   Ord h, Ord i, Ord j)
               => Ord (a, b, c, d, e, f, g, h, i, j)
deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
                   Ord h, Ord i, Ord j, Ord k)
               => Ord (a, b, c, d, e, f, g, h, i, j, k)
deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
                   Ord h, Ord i, Ord j, Ord k, Ord l)
               => Ord (a, b, c, d, e, f, g, h, i, j, k, l)
deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
                   Ord h, Ord i, Ord j, Ord k, Ord l, Ord m)
               => Ord (a, b, c, d, e, f, g, h, i, j, k, l, m)
deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
                   Ord h, Ord i, Ord j, Ord k, Ord l, Ord m, Ord n)
               => Ord (a, b, c, d, e, f, g, h, i, j, k, l, m, n)
deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
                   Ord h, Ord i, Ord j, Ord k, Ord l, Ord m, Ord n, Ord o)
               => Ord (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)

instance (Ord a) => Ord [a] where
    {-# SPECIALISE instance Ord [[Char]] #-}
    {-# SPECIALISE instance Ord [Char] #-}
    {-# SPECIALISE instance Ord [Int] #-}
    compare :: [a] -> [a] -> Ordering
compare []     []     = Ordering
EQ
    compare []     (a
_:[a]
_)  = Ordering
LT
    compare (a
_:[a]
_)  []     = Ordering
GT
    compare (a
x:[a]
xs) (a
y:[a]
ys) = case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
x a
y of
                                Ordering
EQ    -> [a] -> [a] -> Ordering
forall a. Ord a => a -> a -> Ordering
compare [a]
xs [a]
ys
                                Ordering
other -> Ordering
other

deriving instance Ord Bool
deriving instance Ord Ordering

-- We don't use deriving for Ord Char, because for Ord the derived
-- instance defines only compare, which takes two primops.  Then
-- '>' uses compare, and therefore takes two primops instead of one.
instance Ord Char where
    (C# Char#
c1) > :: Char -> Char -> Bool
>  (C# Char#
c2) = Int# -> Bool
isTrue# (Char#
c1 Char# -> Char# -> Int#
`gtChar#` Char#
c2)
    (C# Char#
c1) >= :: Char -> Char -> Bool
>= (C# Char#
c2) = Int# -> Bool
isTrue# (Char#
c1 Char# -> Char# -> Int#
`geChar#` Char#
c2)
    (C# Char#
c1) <= :: Char -> Char -> Bool
<= (C# Char#
c2) = Int# -> Bool
isTrue# (Char#
c1 Char# -> Char# -> Int#
`leChar#` Char#
c2)
    (C# Char#
c1) < :: Char -> Char -> Bool
<  (C# Char#
c2) = Int# -> Bool
isTrue# (Char#
c1 Char# -> Char# -> Int#
`ltChar#` Char#
c2)

-- | Note that due to the presence of @NaN@, `Float`'s 'Ord' instance does not
-- satisfy reflexivity.
--
-- >>> 0/0 <= (0/0 :: Float)
-- False
--
-- Also note that, due to the same, `Ord`'s operator interactions are not
-- respected by `Float`'s instance:
--
-- >>> (0/0 :: Float) > 1
-- False
-- >>> compare (0/0 :: Float) 1
-- GT
instance Ord Float where
    (F# Float#
x) compare :: Float -> Float -> Ordering
`compare` (F# Float#
y)
        = if      Int# -> Bool
isTrue# (Float#
x Float# -> Float# -> Int#
`ltFloat#` Float#
y) then Ordering
LT
          else if Int# -> Bool
isTrue# (Float#
x Float# -> Float# -> Int#
`eqFloat#` Float#
y) then Ordering
EQ
          else                                  Ordering
GT

    (F# Float#
x) < :: Float -> Float -> Bool
<  (F# Float#
y) = Int# -> Bool
isTrue# (Float#
x Float# -> Float# -> Int#
`ltFloat#` Float#
y)
    (F# Float#
x) <= :: Float -> Float -> Bool
<= (F# Float#
y) = Int# -> Bool
isTrue# (Float#
x Float# -> Float# -> Int#
`leFloat#` Float#
y)
    (F# Float#
x) >= :: Float -> Float -> Bool
>= (F# Float#
y) = Int# -> Bool
isTrue# (Float#
x Float# -> Float# -> Int#
`geFloat#` Float#
y)
    (F# Float#
x) > :: Float -> Float -> Bool
>  (F# Float#
y) = Int# -> Bool
isTrue# (Float#
x Float# -> Float# -> Int#
`gtFloat#` Float#
y)

-- | Note that due to the presence of @NaN@, `Double`'s 'Ord' instance does not
-- satisfy reflexivity.
--
-- >>> 0/0 <= (0/0 :: Double)
-- False
--
-- Also note that, due to the same, `Ord`'s operator interactions are not
-- respected by `Double`'s instance:
--
-- >>> (0/0 :: Double) > 1
-- False
-- >>> compare (0/0 :: Double) 1
-- GT
instance Ord Double where
    (D# Double#
x) compare :: Double -> Double -> Ordering
`compare` (D# Double#
y)
        = if      Int# -> Bool
isTrue# (Double#
x Double# -> Double# -> Int#
<##  Double#
y) then Ordering
LT
          else if Int# -> Bool
isTrue# (Double#
x Double# -> Double# -> Int#
==## Double#
y) then Ordering
EQ
          else                            Ordering
GT

    (D# Double#
x) < :: Double -> Double -> Bool
<  (D# Double#
y) = Int# -> Bool
isTrue# (Double#
x Double# -> Double# -> Int#
<##  Double#
y)
    (D# Double#
x) <= :: Double -> Double -> Bool
<= (D# Double#
y) = Int# -> Bool
isTrue# (Double#
x Double# -> Double# -> Int#
<=## Double#
y)
    (D# Double#
x) >= :: Double -> Double -> Bool
>= (D# Double#
y) = Int# -> Bool
isTrue# (Double#
x Double# -> Double# -> Int#
>=## Double#
y)
    (D# Double#
x) > :: Double -> Double -> Bool
>  (D# Double#
y) = Int# -> Bool
isTrue# (Double#
x Double# -> Double# -> Int#
>##  Double#
y)

instance Ord Int where
    compare :: Int -> Int -> Ordering
compare = Int -> Int -> Ordering
compareInt
    < :: Int -> Int -> Bool
(<)     = Int -> Int -> Bool
ltInt
    <= :: Int -> Int -> Bool
(<=)    = Int -> Int -> Bool
leInt
    >= :: Int -> Int -> Bool
(>=)    = Int -> Int -> Bool
geInt
    > :: Int -> Int -> Bool
(>)     = Int -> Int -> Bool
gtInt

-- See GHC.Classes#matching_overloaded_methods_in_rules
{-# INLINE [1] gtInt #-}
{-# INLINE [1] geInt #-}
{-# INLINE [1] ltInt #-}
{-# INLINE [1] leInt #-}
gtInt, geInt, ltInt, leInt :: Int -> Int -> Bool
(I# Int#
x) gtInt :: Int -> Int -> Bool
`gtInt` (I# Int#
y) = Int# -> Bool
isTrue# (Int#
x Int# -> Int# -> Int#
>#  Int#
y)
(I# Int#
x) geInt :: Int -> Int -> Bool
`geInt` (I# Int#
y) = Int# -> Bool
isTrue# (Int#
x Int# -> Int# -> Int#
>=# Int#
y)
(I# Int#
x) ltInt :: Int -> Int -> Bool
`ltInt` (I# Int#
y) = Int# -> Bool
isTrue# (Int#
x Int# -> Int# -> Int#
<#  Int#
y)
(I# Int#
x) leInt :: Int -> Int -> Bool
`leInt` (I# Int#
y) = Int# -> Bool
isTrue# (Int#
x Int# -> Int# -> Int#
<=# Int#
y)

compareInt :: Int -> Int -> Ordering
(I# Int#
x#) compareInt :: Int -> Int -> Ordering
`compareInt` (I# Int#
y#) = Int# -> Int# -> Ordering
compareInt# Int#
x# Int#
y#

compareInt# :: Int# -> Int# -> Ordering
compareInt# :: Int# -> Int# -> Ordering
compareInt# Int#
x# Int#
y#
    | Int# -> Bool
isTrue# (Int#
x# Int# -> Int# -> Int#
<#  Int#
y#) = Ordering
LT
    | Int# -> Bool
isTrue# (Int#
x# Int# -> Int# -> Int#
==# Int#
y#) = Ordering
EQ
    | Bool
True                = Ordering
GT

instance Ord Word where
    compare :: Word -> Word -> Ordering
compare = Word -> Word -> Ordering
compareWord
    < :: Word -> Word -> Bool
(<)     = Word -> Word -> Bool
ltWord
    <= :: Word -> Word -> Bool
(<=)    = Word -> Word -> Bool
leWord
    >= :: Word -> Word -> Bool
(>=)    = Word -> Word -> Bool
geWord
    > :: Word -> Word -> Bool
(>)     = Word -> Word -> Bool
gtWord

-- See GHC.Classes#matching_overloaded_methods_in_rules
{-# INLINE [1] gtWord #-}
{-# INLINE [1] geWord #-}
{-# INLINE [1] ltWord #-}
{-# INLINE [1] leWord #-}
gtWord, geWord, ltWord, leWord :: Word -> Word -> Bool
(W# Word#
x) gtWord :: Word -> Word -> Bool
`gtWord` (W# Word#
y) = Int# -> Bool
isTrue# (Word#
x Word# -> Word# -> Int#
`gtWord#` Word#
y)
(W# Word#
x) geWord :: Word -> Word -> Bool
`geWord` (W# Word#
y) = Int# -> Bool
isTrue# (Word#
x Word# -> Word# -> Int#
`geWord#` Word#
y)
(W# Word#
x) ltWord :: Word -> Word -> Bool
`ltWord` (W# Word#
y) = Int# -> Bool
isTrue# (Word#
x Word# -> Word# -> Int#
`ltWord#` Word#
y)
(W# Word#
x) leWord :: Word -> Word -> Bool
`leWord` (W# Word#
y) = Int# -> Bool
isTrue# (Word#
x Word# -> Word# -> Int#
`leWord#` Word#
y)

compareWord :: Word -> Word -> Ordering
(W# Word#
x#) compareWord :: Word -> Word -> Ordering
`compareWord` (W# Word#
y#) = Word# -> Word# -> Ordering
compareWord# Word#
x# Word#
y#

compareWord# :: Word# -> Word# -> Ordering
compareWord# :: Word# -> Word# -> Ordering
compareWord# Word#
x# Word#
y#
    | Int# -> Bool
isTrue# (Word#
x# Word# -> Word# -> Int#
`ltWord#` Word#
y#) = Ordering
LT
    | Int# -> Bool
isTrue# (Word#
x# Word# -> Word# -> Int#
`eqWord#` Word#
y#) = Ordering
EQ
    | Bool
True                      = Ordering
GT

-- OK, so they're technically not part of a class...:

-- Boolean functions

-- | Boolean \"and\", lazy in the second argument
(&&)                    :: Bool -> Bool -> Bool
Bool
True  && :: Bool -> Bool -> Bool
&& Bool
x              =  Bool
x
Bool
False && Bool
_              =  Bool
False

-- | Boolean \"or\", lazy in the second argument
(||)                    :: Bool -> Bool -> Bool
Bool
True  || :: Bool -> Bool -> Bool
|| Bool
_              =  Bool
True
Bool
False || Bool
x              =  Bool
x

-- | Boolean \"not\"
not                     :: Bool -> Bool
not :: Bool -> Bool
not Bool
True                =  Bool
False
not Bool
False               =  Bool
True


------------------------------------------------------------------------
-- These don't really belong here, but we don't have a better place to
-- put them

-- These functions have built-in rules.
{-# INLINE [0] divInt# #-}
divInt# :: Int# -> Int# -> Int#
Int#
x# divInt# :: Int# -> Int# -> Int#
`divInt#` Int#
y# = ((Int#
x# Int# -> Int# -> Int#
+# Int#
bias#) Int# -> Int# -> Int#
`quotInt#` Int#
y#) Int# -> Int# -> Int#
-# Int#
hard#
   where
      -- See Note [divInt# implementation]
      !yn# :: Int#
yn#   = Int#
y# Int# -> Int# -> Int#
<# Int#
0#
      !c0# :: Int#
c0#   = (Int#
x# Int# -> Int# -> Int#
<# Int#
0#) Int# -> Int# -> Int#
`andI#` (Int# -> Int#
notI# Int#
yn#)
      !c1# :: Int#
c1#   = (Int#
x# Int# -> Int# -> Int#
># Int#
0#) Int# -> Int# -> Int#
`andI#` Int#
yn#
      !bias# :: Int#
bias# = Int#
c0# Int# -> Int# -> Int#
-# Int#
c1#
      !hard# :: Int#
hard# = Int#
c0# Int# -> Int# -> Int#
`orI#` Int#
c1#

{-# INLINE [0] divInt8# #-}
divInt8# :: Int8# -> Int8# -> Int8#
Int8#
x# divInt8# :: Int8# -> Int8# -> Int8#
`divInt8#` Int8#
y# = ((Int8#
x# Int8# -> Int8# -> Int8#
`plusInt8#` Int8#
bias#) Int8# -> Int8# -> Int8#
`quotInt8#` Int8#
y#) Int8# -> Int8# -> Int8#
`subInt8#` Int8#
hard#
   where
      zero# :: Int8#
zero# = Int# -> Int8#
intToInt8# Int#
0#
      Int8#
x andInt8# :: Int8# -> Int8# -> Int8#
`andInt8#` Int8#
y = Word8# -> Int8#
word8ToInt8# (Int8# -> Word8#
int8ToWord8# Int8#
x Word8# -> Word8# -> Word8#
`andWord8#` Int8# -> Word8#
int8ToWord8# Int8#
y)
      Int8#
x orInt8# :: Int8# -> Int8# -> Int8#
`orInt8#` Int8#
y = Word8# -> Int8#
word8ToInt8# (Int8# -> Word8#
int8ToWord8# Int8#
x Word8# -> Word8# -> Word8#
`orWord8#` Int8# -> Word8#
int8ToWord8# Int8#
y)
      notInt8# :: Int8# -> Int8#
notInt8# Int8#
x = Word8# -> Int8#
word8ToInt8# (Word8# -> Word8#
notWord8# (Int8# -> Word8#
int8ToWord8# Int8#
x))
      -- See Note [divInt# implementation]
      !yn# :: Int8#
yn#   = Int# -> Int8#
intToInt8# (Int8#
y# Int8# -> Int8# -> Int#
`ltInt8#` Int8#
zero#)
      !c0# :: Int8#
c0#   = Int# -> Int8#
intToInt8# (Int8#
x# Int8# -> Int8# -> Int#
`ltInt8#` Int8#
zero#) Int8# -> Int8# -> Int8#
`andInt8#` (Int8# -> Int8#
notInt8# Int8#
yn#)
      !c1# :: Int8#
c1#   = Int# -> Int8#
intToInt8# (Int8#
x# Int8# -> Int8# -> Int#
`gtInt8#` Int8#
zero#) Int8# -> Int8# -> Int8#
`andInt8#` Int8#
yn#
      !bias# :: Int8#
bias# = Int8#
c0# Int8# -> Int8# -> Int8#
`subInt8#` Int8#
c1#
      !hard# :: Int8#
hard# = Int8#
c0# Int8# -> Int8# -> Int8#
`orInt8#` Int8#
c1#

{-# INLINE [0] divInt16# #-}
divInt16# :: Int16# -> Int16# -> Int16#
Int16#
x# divInt16# :: Int16# -> Int16# -> Int16#
`divInt16#` Int16#
y# = ((Int16#
x# Int16# -> Int16# -> Int16#
`plusInt16#` Int16#
bias#) Int16# -> Int16# -> Int16#
`quotInt16#` Int16#
y#) Int16# -> Int16# -> Int16#
`subInt16#` Int16#
hard#
   where
      zero# :: Int16#
zero# = Int# -> Int16#
intToInt16# Int#
0#
      Int16#
x andInt16# :: Int16# -> Int16# -> Int16#
`andInt16#` Int16#
y = Word16# -> Int16#
word16ToInt16# (Int16# -> Word16#
int16ToWord16# Int16#
x Word16# -> Word16# -> Word16#
`andWord16#` Int16# -> Word16#
int16ToWord16# Int16#
y)
      Int16#
x orInt16# :: Int16# -> Int16# -> Int16#
`orInt16#` Int16#
y = Word16# -> Int16#
word16ToInt16# (Int16# -> Word16#
int16ToWord16# Int16#
x Word16# -> Word16# -> Word16#
`orWord16#` Int16# -> Word16#
int16ToWord16# Int16#
y)
      notInt16# :: Int16# -> Int16#
notInt16# Int16#
x = Word16# -> Int16#
word16ToInt16# (Word16# -> Word16#
notWord16# (Int16# -> Word16#
int16ToWord16# Int16#
x))
      -- See Note [divInt# implementation]
      !yn# :: Int16#
yn#   = Int# -> Int16#
intToInt16# (Int16#
y# Int16# -> Int16# -> Int#
`ltInt16#` Int16#
zero#)
      !c0# :: Int16#
c0#   = Int# -> Int16#
intToInt16# (Int16#
x# Int16# -> Int16# -> Int#
`ltInt16#` Int16#
zero#) Int16# -> Int16# -> Int16#
`andInt16#` (Int16# -> Int16#
notInt16# Int16#
yn#)
      !c1# :: Int16#
c1#   = Int# -> Int16#
intToInt16# (Int16#
x# Int16# -> Int16# -> Int#
`gtInt16#` Int16#
zero#) Int16# -> Int16# -> Int16#
`andInt16#` Int16#
yn#
      !bias# :: Int16#
bias# = Int16#
c0# Int16# -> Int16# -> Int16#
`subInt16#` Int16#
c1#
      !hard# :: Int16#
hard# = Int16#
c0# Int16# -> Int16# -> Int16#
`orInt16#` Int16#
c1#

{-# INLINE [0] divInt32# #-}
divInt32# :: Int32# -> Int32# -> Int32#
Int32#
x# divInt32# :: Int32# -> Int32# -> Int32#
`divInt32#` Int32#
y# = ((Int32#
x# Int32# -> Int32# -> Int32#
`plusInt32#` Int32#
bias#) Int32# -> Int32# -> Int32#
`quotInt32#` Int32#
y#) Int32# -> Int32# -> Int32#
`subInt32#` Int32#
hard#
   where
      zero# :: Int32#
zero# = Int# -> Int32#
intToInt32# Int#
0#
      Int32#
x andInt32# :: Int32# -> Int32# -> Int32#
`andInt32#` Int32#
y = Word32# -> Int32#
word32ToInt32# (Int32# -> Word32#
int32ToWord32# Int32#
x Word32# -> Word32# -> Word32#
`andWord32#` Int32# -> Word32#
int32ToWord32# Int32#
y)
      Int32#
x orInt32# :: Int32# -> Int32# -> Int32#
`orInt32#` Int32#
y = Word32# -> Int32#
word32ToInt32# (Int32# -> Word32#
int32ToWord32# Int32#
x Word32# -> Word32# -> Word32#
`orWord32#` Int32# -> Word32#
int32ToWord32# Int32#
y)
      notInt32# :: Int32# -> Int32#
notInt32# Int32#
x = Word32# -> Int32#
word32ToInt32# (Word32# -> Word32#
notWord32# (Int32# -> Word32#
int32ToWord32# Int32#
x))
      -- See Note [divInt# implementation]
      !yn# :: Int32#
yn#   = Int# -> Int32#
intToInt32# (Int32#
y# Int32# -> Int32# -> Int#
`ltInt32#` Int32#
zero#)
      !c0# :: Int32#
c0#   = Int# -> Int32#
intToInt32# (Int32#
x# Int32# -> Int32# -> Int#
`ltInt32#` Int32#
zero#) Int32# -> Int32# -> Int32#
`andInt32#` (Int32# -> Int32#
notInt32# Int32#
yn#)
      !c1# :: Int32#
c1#   = Int# -> Int32#
intToInt32# (Int32#
x# Int32# -> Int32# -> Int#
`gtInt32#` Int32#
zero#) Int32# -> Int32# -> Int32#
`andInt32#` Int32#
yn#
      !bias# :: Int32#
bias# = Int32#
c0# Int32# -> Int32# -> Int32#
`subInt32#` Int32#
c1#
      !hard# :: Int32#
hard# = Int32#
c0# Int32# -> Int32# -> Int32#
`orInt32#` Int32#
c1#

-- Note [divInt# implementation]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
-- divInt# (truncated toward zero) is implemented with quotInt# (truncated
-- toward negative infinity). They differ when inputs x and y have different signs:
--  - x `rem` y has the sign of x and (x `quot` y)*y + (x `rem` y) == x
--  - x `mod` y has the sign of y and (x `div`  y)*y + (x `mod` y) == x
--
-- So we bias the input and the result of quotInt as follows:
--
--         if isTrue# (x# ># 0#) && isTrue# (y# <# 0#) then ((x# -# 1#) `quotInt#` y#) -# 1#
--    else if isTrue# (x# <# 0#) && isTrue# (y# ># 0#) then ((x# +# 1#) `quotInt#` y#) -# 1#
--    else x# `quotInt#` y#
--
-- However this leads to assembly code with lots of branches (#19636) while we
-- would like simpler code that we could inline (#18067). So we use some
-- branchless code instead as derived below:
--
--         if isTrue# (x# ># 0#) && isTrue# (y# <# 0#) then ((x# -# 1#) `quotInt#` y#) -# 1#
--    else if isTrue# (x# <# 0#) && isTrue# (y# ># 0#) then ((x# +# 1#) `quotInt#` y#) -# 1#
--    else x# `quotInt#` y#
--
--  ===> { Give names to constants and always use them }
--
--    ((x# +# bias#) `quotInt#` y#) -# hard#
--      where
--        (bias#,hard#)
--          | isTrue# (x# ># 0#) && isTrue# (y# <# 0#) = (-1#, 1#)
--          | isTrue# (x# <# 0#) && isTrue# (y# ># 0#) = ( 1#, 1#)
--          | otherwise                                = ( 0#, 0#)
--
--  ===> { Compute bias# and hard# independently using Bool# (0#,1#) }
--
--    ((x# +# bias#) `quotInt#` y#) -# hard#
--      where
--        c0#   = (x# <# 0#) &&# (y# ># 0#)
--        c1#   = (x# ># 0#) &&# (y# <# 0#)
--        bias# = c0# -# c1#  -- both cases are mutually exclusive so we can subtract them
--        hard# = c0# ||# c1# -- (we could add them too here but OR is slightly better)
--
--  ===> { Use yn# variable for "y# <# 0#" }
--
--    ((x# +# bias#) `quotInt#` y#) -# hard#
--      where
--        -- y# ==# 0# throws an exception so we don't need to consider it
--        yn#   = y# <# 0#
--        c0#   = (x# <# 0#) &&# (notI# yn#)
--        c1#   = (x# ># 0#) &&# yn#
--        bias# = c0# -# c1#
--        hard# = c0# ||# c1#
--
--
-- Note that we need to be careful NOT to overflow if we do any additional
-- arithmetic on the arguments...  the following previous version of this code
-- had problems with overflow:
--    | (x# ># 0#) && (y# <# 0#) = ((x# -# y#) -# 1#) `quotInt#` y#
--    | (x# <# 0#) && (y# ># 0#) = ((x# -# y#) +# 1#) `quotInt#` y#

{-# INLINE [0] modInt# #-}
modInt# :: Int# -> Int# -> Int#
Int#
x# modInt# :: Int# -> Int# -> Int#
`modInt#` Int#
y# = Int#
r# Int# -> Int# -> Int#
+# Int#
k#
  where
    -- See Note [modInt# implementation]
    !yn# :: Int#
yn# = Int#
y# Int# -> Int# -> Int#
<# Int#
0#
    !c0# :: Int#
c0# = (Int#
x# Int# -> Int# -> Int#
<# Int#
0#) Int# -> Int# -> Int#
`andI#` (Int# -> Int#
notI# Int#
yn#)
    !c1# :: Int#
c1# = (Int#
x# Int# -> Int# -> Int#
># Int#
0#) Int# -> Int# -> Int#
`andI#` Int#
yn#
    !s# :: Int#
s#  = Int#
0# Int# -> Int# -> Int#
-# ((Int#
c0# Int# -> Int# -> Int#
`orI#` Int#
c1#) Int# -> Int# -> Int#
`andI#` (Int#
r# Int# -> Int# -> Int#
/=# Int#
0#))
    !k# :: Int#
k#  = Int#
s# Int# -> Int# -> Int#
`andI#` Int#
y#
    !r# :: Int#
r#  = Int#
x# Int# -> Int# -> Int#
`remInt#` Int#
y#

{-# INLINE [0] modInt8# #-}
modInt8# :: Int8# -> Int8# -> Int8#
Int8#
x# modInt8# :: Int8# -> Int8# -> Int8#
`modInt8#` Int8#
y# = Int8#
r# Int8# -> Int8# -> Int8#
`plusInt8#` Int8#
k#
  where
    zero# :: Int8#
zero# = Int# -> Int8#
intToInt8# Int#
0#
    Int8#
x andInt8# :: Int8# -> Int8# -> Int8#
`andInt8#` Int8#
y = Word8# -> Int8#
word8ToInt8# (Int8# -> Word8#
int8ToWord8# Int8#
x Word8# -> Word8# -> Word8#
`andWord8#` Int8# -> Word8#
int8ToWord8# Int8#
y)
    Int8#
x orInt8# :: Int8# -> Int8# -> Int8#
`orInt8#` Int8#
y = Word8# -> Int8#
word8ToInt8# (Int8# -> Word8#
int8ToWord8# Int8#
x Word8# -> Word8# -> Word8#
`orWord8#` Int8# -> Word8#
int8ToWord8# Int8#
y)
    notInt8# :: Int8# -> Int8#
notInt8# Int8#
x = Word8# -> Int8#
word8ToInt8# (Word8# -> Word8#
notWord8# (Int8# -> Word8#
int8ToWord8# Int8#
x))
    -- See Note [modInt# implementation]
    !yn# :: Int8#
yn# = Int# -> Int8#
intToInt8# (Int8#
y# Int8# -> Int8# -> Int#
`ltInt8#` Int8#
zero#)
    !c0# :: Int8#
c0# = Int# -> Int8#
intToInt8# (Int8#
x# Int8# -> Int8# -> Int#
`ltInt8#` Int8#
zero#) Int8# -> Int8# -> Int8#
`andInt8#` (Int8# -> Int8#
notInt8# Int8#
yn#)
    !c1# :: Int8#
c1# = Int# -> Int8#
intToInt8# (Int8#
x# Int8# -> Int8# -> Int#
`gtInt8#` Int8#
zero#) Int8# -> Int8# -> Int8#
`andInt8#` Int8#
yn#
    !s# :: Int8#
s#  = Int8#
zero# Int8# -> Int8# -> Int8#
`subInt8#` ((Int8#
c0# Int8# -> Int8# -> Int8#
`orInt8#` Int8#
c1#) Int8# -> Int8# -> Int8#
`andInt8#` (Int# -> Int8#
intToInt8# (Int8#
r# Int8# -> Int8# -> Int#
`neInt8#` Int8#
zero#)))
    !k# :: Int8#
k#  = Int8#
s# Int8# -> Int8# -> Int8#
`andInt8#` Int8#
y#
    !r# :: Int8#
r#  = Int8#
x# Int8# -> Int8# -> Int8#
`remInt8#` Int8#
y#

{-# INLINE [0] modInt16# #-}
modInt16# :: Int16# -> Int16# -> Int16#
Int16#
x# modInt16# :: Int16# -> Int16# -> Int16#
`modInt16#` Int16#
y# = Int16#
r# Int16# -> Int16# -> Int16#
`plusInt16#` Int16#
k#
  where
    zero# :: Int16#
zero# = Int# -> Int16#
intToInt16# Int#
0#
    Int16#
x andInt16# :: Int16# -> Int16# -> Int16#
`andInt16#` Int16#
y = Word16# -> Int16#
word16ToInt16# (Int16# -> Word16#
int16ToWord16# Int16#
x Word16# -> Word16# -> Word16#
`andWord16#` Int16# -> Word16#
int16ToWord16# Int16#
y)
    Int16#
x orInt16# :: Int16# -> Int16# -> Int16#
`orInt16#` Int16#
y = Word16# -> Int16#
word16ToInt16# (Int16# -> Word16#
int16ToWord16# Int16#
x Word16# -> Word16# -> Word16#
`orWord16#` Int16# -> Word16#
int16ToWord16# Int16#
y)
    notInt16# :: Int16# -> Int16#
notInt16# Int16#
x = Word16# -> Int16#
word16ToInt16# (Word16# -> Word16#
notWord16# (Int16# -> Word16#
int16ToWord16# Int16#
x))
    -- See Note [modInt# implementation]
    !yn# :: Int16#
yn# = Int# -> Int16#
intToInt16# (Int16#
y# Int16# -> Int16# -> Int#
`ltInt16#` Int16#
zero#)
    !c0# :: Int16#
c0# = Int# -> Int16#
intToInt16# (Int16#
x# Int16# -> Int16# -> Int#
`ltInt16#` Int16#
zero#) Int16# -> Int16# -> Int16#
`andInt16#` (Int16# -> Int16#
notInt16# Int16#
yn#)
    !c1# :: Int16#
c1# = Int# -> Int16#
intToInt16# (Int16#
x# Int16# -> Int16# -> Int#
`gtInt16#` Int16#
zero#) Int16# -> Int16# -> Int16#
`andInt16#` Int16#
yn#
    !s# :: Int16#
s#  = Int16#
zero# Int16# -> Int16# -> Int16#
`subInt16#` ((Int16#
c0# Int16# -> Int16# -> Int16#
`orInt16#` Int16#
c1#) Int16# -> Int16# -> Int16#
`andInt16#` (Int# -> Int16#
intToInt16# (Int16#
r# Int16# -> Int16# -> Int#
`neInt16#` Int16#
zero#)))
    !k# :: Int16#
k#  = Int16#
s# Int16# -> Int16# -> Int16#
`andInt16#` Int16#
y#
    !r# :: Int16#
r#  = Int16#
x# Int16# -> Int16# -> Int16#
`remInt16#` Int16#
y#

{-# INLINE [0] modInt32# #-}
modInt32# :: Int32# -> Int32# -> Int32#
Int32#
x# modInt32# :: Int32# -> Int32# -> Int32#
`modInt32#` Int32#
y# = Int32#
r# Int32# -> Int32# -> Int32#
`plusInt32#` Int32#
k#
  where
    zero# :: Int32#
zero# = Int# -> Int32#
intToInt32# Int#
0#
    Int32#
x andInt32# :: Int32# -> Int32# -> Int32#
`andInt32#` Int32#
y = Word32# -> Int32#
word32ToInt32# (Int32# -> Word32#
int32ToWord32# Int32#
x Word32# -> Word32# -> Word32#
`andWord32#` Int32# -> Word32#
int32ToWord32# Int32#
y)
    Int32#
x orInt32# :: Int32# -> Int32# -> Int32#
`orInt32#` Int32#
y = Word32# -> Int32#
word32ToInt32# (Int32# -> Word32#
int32ToWord32# Int32#
x Word32# -> Word32# -> Word32#
`orWord32#` Int32# -> Word32#
int32ToWord32# Int32#
y)
    notInt32# :: Int32# -> Int32#
notInt32# Int32#
x = Word32# -> Int32#
word32ToInt32# (Word32# -> Word32#
notWord32# (Int32# -> Word32#
int32ToWord32# Int32#
x))
    -- See Note [modInt# implementation]
    !yn# :: Int32#
yn# = Int# -> Int32#
intToInt32# (Int32#
y# Int32# -> Int32# -> Int#
`ltInt32#` Int32#
zero#)
    !c0# :: Int32#
c0# = Int# -> Int32#
intToInt32# (Int32#
x# Int32# -> Int32# -> Int#
`ltInt32#` Int32#
zero#) Int32# -> Int32# -> Int32#
`andInt32#` (Int32# -> Int32#
notInt32# Int32#
yn#)
    !c1# :: Int32#
c1# = Int# -> Int32#
intToInt32# (Int32#
x# Int32# -> Int32# -> Int#
`gtInt32#` Int32#
zero#) Int32# -> Int32# -> Int32#
`andInt32#` Int32#
yn#
    !s# :: Int32#
s#  = Int32#
zero# Int32# -> Int32# -> Int32#
`subInt32#` ((Int32#
c0# Int32# -> Int32# -> Int32#
`orInt32#` Int32#
c1#) Int32# -> Int32# -> Int32#
`andInt32#` (Int# -> Int32#
intToInt32# (Int32#
r# Int32# -> Int32# -> Int#
`neInt32#` Int32#
zero#)))
    !k# :: Int32#
k#  = Int32#
s# Int32# -> Int32# -> Int32#
`andInt32#` Int32#
y#
    !r# :: Int32#
r#  = Int32#
x# Int32# -> Int32# -> Int32#
`remInt32#` Int32#
y#

-- Note [modInt# implementation]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
-- Similarly to divInt# (see Note [divInt# implementation]), we can derive the
-- branchless implementation of modInt# as follows:
--
--    = if isTrue# (x# ># 0#) && isTrue# (y# <# 0#) ||
--         isTrue# (x# <# 0#) && isTrue# (y# ># 0#)
--      then if isTrue# (r# /=# 0#) then r# +# y# else 0#
--      else r#
--    where
--     r# = x# `remInt#` y#
--
--  ===> { Introduce constant k# }
--
--    r# +# k#
--      where
--        k# = if isTrue# (x# ># 0#) && isTrue# (y# <# 0#) ||
--                isTrue# (x# <# 0#) && isTrue# (y# ># 0#)
--             then if isTrue# (r# /=# 0#) then y# else 0#
--             else 0#
--        r# = x# `remInt#` y#
--
--  ===> { Compute using Bool# }
--
--    r# +# k#
--      where
--        yn# = y# <# 0# -- we don't need to consider y# ==# 0#
--        c0# = (x# <# 0#) &&# (notI# yn#)
--        c1# = (x# ># 0#) &&# yn#
--        k#  = if isTrue# ((c0# ||# c1#) &&# (r# /=# 0#))
--                then y#
--                else 0#
--        r#  = x# `remInt#` y#
--
--  ===> { Select y# or 0# in branchless way }
--
--    r# +# k#
--      where
--        yn# = y# <# 0#
--        c0# = (x# <# 0#) &&# (notI# yn#)
--        c1# = (x# ># 0#) &&# yn#
--        -- s# is either equal to:
--        --    0#  (00..00b)
--        --    -1# (11..11b)
--        -- So we can AND s# with y#
--        s#  = 0# -# ((c0# ||# c1#) &&# (r# /=# 0#))
--        k#  = s# &&# y#
--        r#  = x# `remInt#` y#

{-# INLINE [0] divModInt# #-}
divModInt# :: Int# -> Int# -> (# Int#, Int# #)
Int#
x# divModInt# :: Int# -> Int# -> (# Int#, Int# #)
`divModInt#` Int#
y# = case (Int#
x# Int# -> Int# -> Int#
+# Int#
bias#) Int# -> Int# -> (# Int#, Int# #)
`quotRemInt#` Int#
y# of
  (# Int#
q#, Int#
r# #) -> (# Int#
q# Int# -> Int# -> Int#
-# Int#
hard#, Int#
r# Int# -> Int# -> Int#
+# Int#
k# #)
  where
    -- See Note [divModInt# implementation]
    !yn# :: Int#
yn#   = Int#
y# Int# -> Int# -> Int#
<# Int#
0#
    !c0# :: Int#
c0#   = (Int#
x# Int# -> Int# -> Int#
<# Int#
0#) Int# -> Int# -> Int#
`andI#` (Int# -> Int#
notI# Int#
yn#)
    !c1# :: Int#
c1#   = (Int#
x# Int# -> Int# -> Int#
># Int#
0#) Int# -> Int# -> Int#
`andI#` Int#
yn#
    !bias# :: Int#
bias# = Int#
c0# Int# -> Int# -> Int#
-# Int#
c1#
    !hard# :: Int#
hard# = Int#
c0# Int# -> Int# -> Int#
`orI#` Int#
c1#
    !s# :: Int#
s#    = Int#
0# Int# -> Int# -> Int#
-# Int#
hard#
    !k# :: Int#
k#    = (Int#
s# Int# -> Int# -> Int#
`andI#` Int#
y#) Int# -> Int# -> Int#
-# Int#
bias#

{-# INLINE [0] divModInt8# #-}
divModInt8# :: Int8# -> Int8# -> (# Int8#, Int8# #)
Int8#
x# divModInt8# :: Int8# -> Int8# -> (# Int8#, Int8# #)
`divModInt8#` Int8#
y# = case (Int8#
x# Int8# -> Int8# -> Int8#
`plusInt8#` Int8#
bias#) Int8# -> Int8# -> (# Int8#, Int8# #)
`quotRemInt8#` Int8#
y# of
  (# Int8#
q#, Int8#
r# #) -> (# Int8#
q# Int8# -> Int8# -> Int8#
`subInt8#` Int8#
hard#, Int8#
r# Int8# -> Int8# -> Int8#
`plusInt8#` Int8#
k# #)
  where
    zero# :: Int8#
zero# = Int# -> Int8#
intToInt8# Int#
0#
    Int8#
x andInt8# :: Int8# -> Int8# -> Int8#
`andInt8#` Int8#
y = Word8# -> Int8#
word8ToInt8# (Int8# -> Word8#
int8ToWord8# Int8#
x Word8# -> Word8# -> Word8#
`andWord8#` Int8# -> Word8#
int8ToWord8# Int8#
y)
    Int8#
x orInt8# :: Int8# -> Int8# -> Int8#
`orInt8#` Int8#
y = Word8# -> Int8#
word8ToInt8# (Int8# -> Word8#
int8ToWord8# Int8#
x Word8# -> Word8# -> Word8#
`orWord8#` Int8# -> Word8#
int8ToWord8# Int8#
y)
    notInt8# :: Int8# -> Int8#
notInt8# Int8#
x = Word8# -> Int8#
word8ToInt8# (Word8# -> Word8#
notWord8# (Int8# -> Word8#
int8ToWord8# Int8#
x))
    -- See Note [divModInt# implementation]
    !yn# :: Int8#
yn#   = Int# -> Int8#
intToInt8# (Int8#
y# Int8# -> Int8# -> Int#
`ltInt8#` Int8#
zero#)
    !c0# :: Int8#
c0#   = Int# -> Int8#
intToInt8# (Int8#
x# Int8# -> Int8# -> Int#
`ltInt8#` Int8#
zero#) Int8# -> Int8# -> Int8#
`andInt8#` (Int8# -> Int8#
notInt8# Int8#
yn#)
    !c1# :: Int8#
c1#   = Int# -> Int8#
intToInt8# (Int8#
x# Int8# -> Int8# -> Int#
`gtInt8#` Int8#
zero#) Int8# -> Int8# -> Int8#
`andInt8#` Int8#
yn#
    !bias# :: Int8#
bias# = Int8#
c0# Int8# -> Int8# -> Int8#
`subInt8#` Int8#
c1#
    !hard# :: Int8#
hard# = Int8#
c0# Int8# -> Int8# -> Int8#
`orInt8#` Int8#
c1#
    !s# :: Int8#
s#    = Int8#
zero# Int8# -> Int8# -> Int8#
`subInt8#` Int8#
hard#
    !k# :: Int8#
k#    = (Int8#
s# Int8# -> Int8# -> Int8#
`andInt8#` Int8#
y#) Int8# -> Int8# -> Int8#
`subInt8#` Int8#
bias#

{-# INLINE [0] divModInt16# #-}
divModInt16# :: Int16# -> Int16# -> (# Int16#, Int16# #)
Int16#
x# divModInt16# :: Int16# -> Int16# -> (# Int16#, Int16# #)
`divModInt16#` Int16#
y# = case (Int16#
x# Int16# -> Int16# -> Int16#
`plusInt16#` Int16#
bias#) Int16# -> Int16# -> (# Int16#, Int16# #)
`quotRemInt16#` Int16#
y# of
  (# Int16#
q#, Int16#
r# #) -> (# Int16#
q# Int16# -> Int16# -> Int16#
`subInt16#` Int16#
hard#, Int16#
r# Int16# -> Int16# -> Int16#
`plusInt16#` Int16#
k# #)
  where
    zero# :: Int16#
zero# = Int# -> Int16#
intToInt16# Int#
0#
    Int16#
x andInt16# :: Int16# -> Int16# -> Int16#
`andInt16#` Int16#
y = Word16# -> Int16#
word16ToInt16# (Int16# -> Word16#
int16ToWord16# Int16#
x Word16# -> Word16# -> Word16#
`andWord16#` Int16# -> Word16#
int16ToWord16# Int16#
y)
    Int16#
x orInt16# :: Int16# -> Int16# -> Int16#
`orInt16#` Int16#
y = Word16# -> Int16#
word16ToInt16# (Int16# -> Word16#
int16ToWord16# Int16#
x Word16# -> Word16# -> Word16#
`orWord16#` Int16# -> Word16#
int16ToWord16# Int16#
y)
    notInt16# :: Int16# -> Int16#
notInt16# Int16#
x = Word16# -> Int16#
word16ToInt16# (Word16# -> Word16#
notWord16# (Int16# -> Word16#
int16ToWord16# Int16#
x))
    -- See Note [divModInt# implementation]
    !yn# :: Int16#
yn#   = Int# -> Int16#
intToInt16# (Int16#
y# Int16# -> Int16# -> Int#
`ltInt16#` Int16#
zero#)
    !c0# :: Int16#
c0#   = Int# -> Int16#
intToInt16# (Int16#
x# Int16# -> Int16# -> Int#
`ltInt16#` Int16#
zero#) Int16# -> Int16# -> Int16#
`andInt16#` (Int16# -> Int16#
notInt16# Int16#
yn#)
    !c1# :: Int16#
c1#   = Int# -> Int16#
intToInt16# (Int16#
x# Int16# -> Int16# -> Int#
`gtInt16#` Int16#
zero#) Int16# -> Int16# -> Int16#
`andInt16#` Int16#
yn#
    !bias# :: Int16#
bias# = Int16#
c0# Int16# -> Int16# -> Int16#
`subInt16#` Int16#
c1#
    !hard# :: Int16#
hard# = Int16#
c0# Int16# -> Int16# -> Int16#
`orInt16#` Int16#
c1#
    !s# :: Int16#
s#    = Int16#
zero# Int16# -> Int16# -> Int16#
`subInt16#` Int16#
hard#
    !k# :: Int16#
k#    = (Int16#
s# Int16# -> Int16# -> Int16#
`andInt16#` Int16#
y#) Int16# -> Int16# -> Int16#
`subInt16#` Int16#
bias#

{-# INLINE [0] divModInt32# #-}
divModInt32# :: Int32# -> Int32# -> (# Int32#, Int32# #)
Int32#
x# divModInt32# :: Int32# -> Int32# -> (# Int32#, Int32# #)
`divModInt32#` Int32#
y# = case (Int32#
x# Int32# -> Int32# -> Int32#
`plusInt32#` Int32#
bias#) Int32# -> Int32# -> (# Int32#, Int32# #)
`quotRemInt32#` Int32#
y# of
  (# Int32#
q#, Int32#
r# #) -> (# Int32#
q# Int32# -> Int32# -> Int32#
`subInt32#` Int32#
hard#, Int32#
r# Int32# -> Int32# -> Int32#
`plusInt32#` Int32#
k# #)
  where
    zero# :: Int32#
zero# = Int# -> Int32#
intToInt32# Int#
0#
    Int32#
x andInt32# :: Int32# -> Int32# -> Int32#
`andInt32#` Int32#
y = Word32# -> Int32#
word32ToInt32# (Int32# -> Word32#
int32ToWord32# Int32#
x Word32# -> Word32# -> Word32#
`andWord32#` Int32# -> Word32#
int32ToWord32# Int32#
y)
    Int32#
x orInt32# :: Int32# -> Int32# -> Int32#
`orInt32#` Int32#
y = Word32# -> Int32#
word32ToInt32# (Int32# -> Word32#
int32ToWord32# Int32#
x Word32# -> Word32# -> Word32#
`orWord32#` Int32# -> Word32#
int32ToWord32# Int32#
y)
    notInt32# :: Int32# -> Int32#
notInt32# Int32#
x = Word32# -> Int32#
word32ToInt32# (Word32# -> Word32#
notWord32# (Int32# -> Word32#
int32ToWord32# Int32#
x))
    -- See Note [divModInt# implementation]
    !yn# :: Int32#
yn#   = Int# -> Int32#
intToInt32# (Int32#
y# Int32# -> Int32# -> Int#
`ltInt32#` Int32#
zero#)
    !c0# :: Int32#
c0#   = Int# -> Int32#
intToInt32# (Int32#
x# Int32# -> Int32# -> Int#
`ltInt32#` Int32#
zero#) Int32# -> Int32# -> Int32#
`andInt32#` (Int32# -> Int32#
notInt32# Int32#
yn#)
    !c1# :: Int32#
c1#   = Int# -> Int32#
intToInt32# (Int32#
x# Int32# -> Int32# -> Int#
`gtInt32#` Int32#
zero#) Int32# -> Int32# -> Int32#
`andInt32#` Int32#
yn#
    !bias# :: Int32#
bias# = Int32#
c0# Int32# -> Int32# -> Int32#
`subInt32#` Int32#
c1#
    !hard# :: Int32#
hard# = Int32#
c0# Int32# -> Int32# -> Int32#
`orInt32#` Int32#
c1#
    !s# :: Int32#
s#    = Int32#
zero# Int32# -> Int32# -> Int32#
`subInt32#` Int32#
hard#
    !k# :: Int32#
k#    = (Int32#
s# Int32# -> Int32# -> Int32#
`andInt32#` Int32#
y#) Int32# -> Int32# -> Int32#
`subInt32#` Int32#
bias#

-- Note [divModInt# implementation]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
-- divModInt# is written by deriving the following code similarly to divInt# and
-- modInt# (see Note [divInt# implementation] and Note [modInt#
-- implementation]).
--
--    x# `divModInt#` y#
--     | isTrue# (x# ># 0#) && isTrue# (y# <# 0#) =
--                                        case (x# -# 1#) `quotRemInt#` y# of
--                                          (# q, r #) -> (# q -# 1#, r +# y# +# 1# #)
--     | isTrue# (x# <# 0#) && isTrue# (y# ># 0#) =
--                                        case (x# +# 1#) `quotRemInt#` y# of
--                                          (# q, r #) -> (# q -# 1#, r +# y# -# 1# #)
--     | otherwise                                =
--                                        x# `quotRemInt#` y#
--
--  ===> { Introduce constants }
--
--    case (x# +# bias#) `quotRemInt#` y# of
--      (# q#, r# #) -> (# q# -# hard#, r# +# k# #)
--      where
--       (bias#,hard#,k#)
--        | isTrue# (x# ># 0#) && isTrue# (y# <# 0#) = (-1#, 1#, y#+1#)
--        | isTrue# (x# <# 0#) && isTrue# (y# ># 0#) = ( 1#, 1#, y#-1#)
--        | otherwise                                = ( 0#, 0#, 0#-0#)
--
--  ===> { Compute using Bool# }
--
--    case (x# +# bias#) `quotRemInt#` y# of
--      (# q#, r# #) -> (# q# -# hard#, r# +# k# #)
--      where
--        yn#   = y# <# 0#
--        c0#   = (x# <# 0#) `andI#` (notI# yn#)
--        c1#   = (x# ># 0#) `andI#` yn#
--        bias# = c0# -# c1#
--        hard# = c0# `orI#` c1#
--        s#    = 0# -# hard#
--        k#    = (s# `andI#` y#) -# bias#
--

{- *************************************************************
*                                                              *
*               Constraint tuples                              *
*                                                              *
************************************************************* -}

class ()
class (c1, c2)     => (c1, c2)
class (c1, c2, c3) => (c1, c2, c3)
class (c1, c2, c3, c4) => (c1, c2, c3, c4)
class (c1, c2, c3, c4, c5) => (c1, c2, c3, c4, c5)
class (c1, c2, c3, c4, c5, c6) => (c1, c2, c3, c4, c5, c6)
class (c1, c2, c3, c4, c5, c6, c7) => (c1, c2, c3, c4, c5, c6, c7)
class (c1, c2, c3, c4, c5, c6, c7, c8) => (c1, c2, c3, c4, c5, c6, c7, c8)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17,c18)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
       c59)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
       c59)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
       c59, c60)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
       c59, c60)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
       c59, c60, c61)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
       c59, c60, c61)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
       c59, c60, c61, c62)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
       c59, c60, c61, c62)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
       c59, c60, c61, c62, c63)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
       c59, c60, c61, c62, c63)
class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
       c59, c60, c61, c62, c63, c64)
   => (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
       c59, c60, c61, c62, c63, c64)