{-# LANGUAGE CPP, Trustworthy #-} {-# LANGUAGE NoImplicitPrelude, MagicHash, StandaloneDeriving, BangPatterns, KindSignatures, DataKinds, ConstraintKinds, MultiParamTypeClasses, FunctionalDependencies #-} {-# 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#, modInt# ) 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 forall a. Eq a => a -> a -> Bool == a y) a x == a y = Bool -> Bool not (a x 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 forall a. Eq a => a -> a -> Bool == a y Bool -> Bool -> Bool && [a] xs 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 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 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 forall a. Ord a => a -> a -> Bool <= a y then Ordering LT else Ordering GT a x < a y = case 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 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 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 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 forall a. Ord a => a -> a -> Bool <= a y then a y else a x min a x a y = if a x 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 forall a. Ord a => a -> a -> Ordering compare a x a y of Ordering EQ -> 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. {-# NOINLINE [0] divInt# #-} {-# NOINLINE [0] modInt# #-} divInt# :: Int# -> Int# -> Int# Int# x# divInt# :: Int# -> Int# -> Int# `divInt#` Int# y# -- Be careful NOT to overflow if we do any additional arithmetic -- on the arguments... the following previous version of this -- code has problems with overflow: -- | (x# ># 0#) && (y# <# 0#) = ((x# -# y#) -# 1#) `quotInt#` y# -- | (x# <# 0#) && (y# ># 0#) = ((x# -# y#) +# 1#) `quotInt#` y# = if Int# -> Bool isTrue# (Int# x# Int# -> Int# -> Int# ># Int# 0#) Bool -> Bool -> Bool && Int# -> Bool isTrue# (Int# y# Int# -> Int# -> Int# <# Int# 0#) then ((Int# x# Int# -> Int# -> Int# -# Int# 1#) Int# -> Int# -> Int# `quotInt#` Int# y#) Int# -> Int# -> Int# -# Int# 1# else if Int# -> Bool isTrue# (Int# x# Int# -> Int# -> Int# <# Int# 0#) Bool -> Bool -> Bool && Int# -> Bool isTrue# (Int# y# Int# -> Int# -> Int# ># Int# 0#) then ((Int# x# Int# -> Int# -> Int# +# Int# 1#) Int# -> Int# -> Int# `quotInt#` Int# y#) Int# -> Int# -> Int# -# Int# 1# else Int# x# Int# -> Int# -> Int# `quotInt#` Int# y# modInt# :: Int# -> Int# -> Int# Int# x# modInt# :: Int# -> Int# -> Int# `modInt#` Int# y# = if Int# -> Bool isTrue# (Int# x# Int# -> Int# -> Int# ># Int# 0#) Bool -> Bool -> Bool && Int# -> Bool isTrue# (Int# y# Int# -> Int# -> Int# <# Int# 0#) Bool -> Bool -> Bool || Int# -> Bool isTrue# (Int# x# Int# -> Int# -> Int# <# Int# 0#) Bool -> Bool -> Bool && Int# -> Bool isTrue# (Int# y# Int# -> Int# -> Int# ># Int# 0#) then if Int# -> Bool isTrue# (Int# r# Int# -> Int# -> Int# /=# Int# 0#) then Int# r# Int# -> Int# -> Int# +# Int# y# else Int# 0# else Int# r# where !r# :: Int# r# = Int# x# Int# -> Int# -> Int# `remInt#` Int# y# {- ************************************************************* * * * 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, <