module Prelude ( module PreludeList, module PreludeText, module PreludeIO, module Prelude{- Bool(False, True), Maybe(Nothing, Just), Either(Left, Right), Ordering(LT, EQ, GT), Char, String, Int, Integer, Float, Double, Rational, IO, -- These built-in types are defined in the Prelude, but -- are denoted by built-in syntax, and cannot legally -- appear in an export list. -- List type: []((:), []) -- Tuple types: (,), (,,), etc. -- Trivial type: () -- Functions: (->) Eq((==), (/=)), Ord(compare, (<), (<=), (>=), (>), max, min), Enum(succ, pred, toEnum, fromEnum, enumFrom, enumFromThen, enumFromTo, enumFromThenTo), Bounded(minBound, maxBound), Num((+), (-), (*), negate, abs, signum, fromInteger), Real(toRational), Integral(quot, rem, div, mod, quotRem, divMod, toInteger), Fractional((/), recip, fromRational), Floating(pi, exp, log, sqrt, (**), logBase, sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh), RealFrac(properFraction, truncate, round, ceiling, floor), RealFloat(floatRadix, floatDigits, floatRange, decodeFloat, encodeFloat, exponent, significand, scaleFloat, isNaN, isInfinite, isDenormalized, isIEEE, isNegativeZero, atan2), Monad((>>=), (>>), return, fail), Functor(fmap), mapM, mapM_, sequence, sequence_, (=<<), maybe, either, (&&), (||), not, otherwise, subtract, even, odd, gcd, lcm, (^), (^^), fromIntegral, realToFrac, fst, snd, curry, uncurry, id, const, (.), flip, ($), until, asTypeOf, error, undefined, seq, ($!)-} ) where import PreludeBuiltin -- Contains all `prim' values import PreludeList import PreludeText import PreludeIO(FilePath, IOError, ioError, userError, catch, putChar, putStr, putStrLn, print, getChar, getLine, getContents, interact, readFile, writeFile, appendFile, readIO, readLn) import Ratio( Ratio ) import Ix type Rational = Ratio Integer -- the type checker refers to Prelude.Rational!!! infixr 9 . infixr 8 ^, ^^, ** infixl 7 *, /, `quot`, `rem`, `div`, `mod` infixl 6 +, - -- The (:) operator is built-in syntax, and cannot legally be given -- a fixity declaration; but its fixity is given by: infixr 5 : infix 4 ==, /=, <, <=, >=, > infixr 3 && infixr 2 || infixl 1 >>, >>= infixr 1 =<< infixr 0 $, $!, `seq` -- Standard types, classes, instances and related functions -- Equality and Ordered classes class Eq a where (==), (/=) :: a -> a -> Bool -- Minimal complete definition: -- (==) or (/=) x /= y = not (x == y) x == y = not (x /= y) class (Eq a) => Ord a where compare :: a -> a -> Ordering (<), (<=), (>=), (>) :: a -> a -> Bool max, min :: a -> a -> a -- Minimal complete definition: -- (<=) or compare -- Using compare can be more efficient for complex types. compare x y | x == y = EQ | x <= y = LT | otherwise = GT x <= y = compare x y /= GT x < y = compare x y == LT x >= y = compare x y /= LT x > y = compare x y == GT -- note that (min x y, max x y) = (x,y) or (y,x) max x y | x <= y = y | otherwise = x min x y | x <= y = x | otherwise = y -- Enumeration and Bounded classes class Enum a where succ, pred :: a -> a toEnum :: Int -> a fromEnum :: a -> Int enumFrom :: a -> [a] -- [n..] enumFromThen :: a -> a -> [a] -- [n,n'..] enumFromTo :: a -> a -> [a] -- [n..m] enumFromThenTo :: a -> a -> a -> [a] -- [n,n'..m] -- Minimal complete definition: -- toEnum, fromEnum -- -- NOTE: these default methods only make sense for types -- that map injectively into Int using fromEnum -- and toEnum. succ = toEnum . (+1) . fromEnum pred = toEnum . (subtract 1) . fromEnum enumFrom x = map toEnum [fromEnum x ..] enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] enumFromThenTo x y z = map toEnum [fromEnum x, fromEnum y .. fromEnum z] class Bounded a where minBound :: a maxBound :: a -- Numeric classes class (Eq a, Show a) => Num a where (+), (-), (*) :: a -> a -> a negate :: a -> a abs, signum :: a -> a fromInteger :: Integer -> a -- Minimal complete definition: -- All, except negate or (-) x - y = x + negate y negate x = 0 - x class (Num a, Ord a) => Real a where toRational :: a -> Rational class (Real a, Enum a) => Integral a where quot, rem :: a -> a -> a div, mod :: a -> a -> a quotRem, divMod :: a -> a -> (a,a) toInteger :: a -> Integer -- Minimal complete definition: -- quotRem, toInteger n `quot` d = q where (q,r) = quotRem n d n `rem` d = r where (q,r) = quotRem n d n `div` d = q where (q,r) = divMod n d n `mod` d = r where (q,r) = divMod n d divMod n d = if signum r == - signum d then (q-1, r+d) else qr where qr@(q,r) = quotRem n d class (Num a) => Fractional a where (/) :: a -> a -> a recip :: a -> a fromRational :: Rational -> a -- Minimal complete definition: -- fromRational and (recip or (/)) recip x = 1 / x x / y = x * recip y class (Fractional a) => Floating a where pi :: a exp, log, sqrt :: a -> a (**), logBase :: a -> a -> a sin, cos, tan :: a -> a asin, acos, atan :: a -> a sinh, cosh, tanh :: a -> a asinh, acosh, atanh :: a -> a -- Minimal complete definition: -- pi, exp, log, sin, cos, sinh, cosh -- asin, acos, atan -- asinh, acosh, atanh x ** y = exp (log x * y) logBase x y = log y / log x sqrt x = x ** 0.5 tan x = sin x / cos x tanh x = sinh x / cosh x class (Real a, Fractional a) => RealFrac a where properFraction :: (Integral b) => a -> (b,a) truncate, round :: (Integral b) => a -> b ceiling, floor :: (Integral b) => a -> b -- Minimal complete definition: -- properFraction truncate x = m where (m,_) = properFraction x round x = let (n,r) = properFraction x m = if r < 0 then n - 1 else n + 1 in case signum (abs r - 0.5) of -1 -> n 0 -> if even n then n else m 1 -> m ceiling x = if r > 0 then n + 1 else n where (n,r) = properFraction x floor x = if r < 0 then n - 1 else n where (n,r) = properFraction x class (RealFrac a, Floating a) => RealFloat a where floatRadix :: a -> Integer floatDigits :: a -> Int floatRange :: a -> (Int,Int) decodeFloat :: a -> (Integer,Int) encodeFloat :: Integer -> Int -> a exponent :: a -> Int significand :: a -> a scaleFloat :: Int -> a -> a isNaN, isInfinite, isDenormalized, isNegativeZero, isIEEE :: a -> Bool atan2 :: a -> a -> a -- Minimal complete definition: -- All except exponent, significand, -- scaleFloat, atan2 exponent x = if m == 0 then 0 else n + floatDigits x where (m,n) = decodeFloat x significand x = encodeFloat m (- floatDigits x) where (m,_) = decodeFloat x scaleFloat k x = encodeFloat m (n+k) where (m,n) = decodeFloat x atan2 y x | x>0 = atan (y/x) | x==0 && y>0 = pi/2 | x<0 && y>0 = pi + atan (y/x) |(x<=0 && y<0) || (x<0 && isNegativeZero y) || (isNegativeZero x && isNegativeZero y) = -atan2 (-y) x | y==0 && (x<0 || isNegativeZero x) = pi -- must be after the previous test on zero y | x==0 && y==0 = y -- must be after the other double zero tests | otherwise = x + y -- x or y is a NaN, return a NaN (via +) -- Numeric functions subtract :: (Num a) => a -> a -> a subtract = flip (-) even, odd :: (Integral a) => a -> Bool even n = n `rem` 2 == 0 odd n = not (even n) gcd :: (Integral a) => a -> a -> a gcd 0 0 = error "Prelude.gcd: gcd 0 0 is undefined" gcd x y = gcd' (abs x) (abs y) where gcd' x 0 = x gcd' x y = gcd' y (x `rem` y) lcm :: (Integral a) => a -> a -> a lcm _ 0 = 0 lcm 0 _ = 0 lcm x y = abs ((x `quot` (gcd x y)) * y) (^) :: (Num a, Integral b) => a -> b -> a x ^ 0 = 1 x ^ n | n > 0 = f x (n-1) x where f _ 0 y = y f x n y = if n==0 then y else g x n where g x n | even n = g (x*x) (n `quot` 2) | otherwise = f x (n-1) (x*y) _ ^ _ = error "Prelude.^: negative exponent" (^^) :: (Fractional a, Integral b) => a -> b -> a x ^^ n = if n >= 0 then x^n else recip (x^(-n)) fromIntegral :: (Integral a, Num b) => a -> b fromIntegral = fromInteger . toInteger realToFrac :: (Real a, Fractional b) => a -> b realToFrac = fromRational . toRational -- Monadic classes class Functor f where fmap :: (a -> b) -> f a -> f b class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a fail :: String -> m a -- Minimal complete definition: -- (>>=), return m >> k = m >>= \ x -> k fail s = error s sequence :: Monad m => [m a] -> m [a] sequence = foldr mcons (return []) where mcons p q = p >>= \x -> q >>= \y -> return (x:y) sequence_ :: Monad m => [m a] -> m () sequence_ = foldr (>>) (return ()) -- The xxxM functions take list arguments, but lift the function or -- list element to a monad type mapM :: Monad m => (a -> m b) -> [a] -> m [b] mapM f as = sequence (map f as) mapM_ :: Monad m => (a -> m b) -> [a] -> m () mapM_ f as = sequence_ (map f as) (=<<) :: Monad m => (a -> m b) -> m a -> m b f =<< x = x >>= f -- Trivial type data () = () deriving (Eq, Ord, Enum, Bounded, Ix) -- Function type --data a -> b -- No constructor for functions is exported. data (->) a b -- identity function id :: a -> a id x = x -- constant function const :: a -> b -> a const x _ = x -- function composition (.) :: (b -> c) -> (a -> b) -> a -> c f . g = \ x -> f (g x) -- flip f takes its (first) two arguments in the reverse order of f. flip :: (a -> b -> c) -> b -> a -> c flip f x y = f y x seq = primSeq -- right-associating infix application operators -- (useful in continuation-passing style) ($), ($!) :: (a -> b) -> a -> b f $ x = f x f $! x = x `seq` f x -- Boolean type data Bool = False | True deriving (Eq, Ord, Enum, Read, Show, Bounded, Ix) -- Boolean functions (&&), (||) :: Bool -> Bool -> Bool True && x = x False && _ = False True || _ = True False || x = x not :: Bool -> Bool not True = False not False = True otherwise :: Bool otherwise = True -- Character type data Char -- = ... 'a' | 'b' ... -- 2^16 unicode values instance Eq Char where c == c' = fromEnum c == fromEnum c' instance Ord Char where c <= c' = fromEnum c <= fromEnum c' instance Enum Char where toEnum = primIntToChar fromEnum = primCharToInt enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Char)] enumFromThen c c' = map toEnum [fromEnum c, fromEnum c' .. fromEnum lastChar] where lastChar :: Char lastChar | c' < c = minBound | otherwise = maxBound instance Bounded Char where minBound = '\0' maxBound = primUnicodeMaxChar type String = [Char] -- Maybe type data Maybe a = Nothing | Just a deriving (Eq, Ord, Read, Show) maybe :: b -> (a -> b) -> Maybe a -> b maybe n f Nothing = n maybe n f (Just x) = f x instance Functor Maybe where fmap f Nothing = Nothing fmap f (Just x) = Just (f x) instance Monad Maybe where (Just x) >>= k = k x Nothing >>= k = Nothing return = Just fail s = Nothing -- Either type data Either a b = Left a | Right b deriving (Eq, Ord, Read, Show) either :: (a -> c) -> (b -> c) -> Either a b -> c either f g (Left x) = f x either f g (Right y) = g y -- IO type data IO a -- abstract instance Functor IO where fmap f x = x >>= (return . f) instance Monad IO where (>>=) = undefined -- ... return = undefined -- ... fail s = ioError (userError s) -- Ordering type data Ordering = LT | EQ | GT deriving (Eq, Ord, Enum, Read, Show, Bounded, Ix) --instance Eq Ordering -- For use in derived Ord instances: lexOrder EQ o = o lexOrder o _ = o -- Standard numeric types. The data declarations for these types cannot -- be expressed directly in Haskell since the constructor lists would be -- far too large. data Int -- = minBound ... -1 | 0 | 1 ... maxBound instance Eq Int where (==) = primIntEq instance Ord Int where (<=) = primIntLte instance Num Int where (+) = primIntAdd; (-) = primIntSub; (*) = primIntMul negate = primIntNegate; abs = primIntAbs; signum = primIntSignum fromInteger = primInteger2Int instance Real Int --where ... instance Integral Int where toInteger = primInt2Integer n `quotRem` d = (n `primIntQuot` d,n `primIntRem` d) instance Enum Int where toEnum = id; fromEnum = id instance Bounded Int --where ... data Integer -- = ... -1 | 0 | 1 ... instance Eq Integer where (==) = primIntegerEq instance Ord Integer where (<=) = primIntegerLte instance Num Integer where (+) = primIntegerAdd; (-) = primIntegerSub; (*) = primIntegerMul negate = primIntegerNegate; abs = primIntegerAbs; signum = primIntegerSignum fromInteger = id instance Enum Integer where succ x = x+1 pred x = x-1 toEnum = primInt2Integer fromEnum = fromInteger enumFrom x = x:enumFrom (succ x) enumFromTo x y = if x<=y then x:enumFromTo (succ x) y else [] instance Real Integer --where ... instance Integral Integer where toInteger = id n `quotRem` d = (n `primIntegerQuot` d,n `primIntegerRem` d) data Float instance Eq Float where (==) = undefined -- avoid looping instance Ord Float where (<=) = undefined -- avoid looping instance Num Float --where ... instance Real Float --where ... instance Fractional Float --where ... instance Floating Float --where ... instance RealFrac Float --where ... instance RealFloat Float --where ... data Double instance Eq Double where (==) = undefined -- avoid looping instance Ord Double where (<=) = undefined -- avoid looping instance Num Double --where ... instance Real Double --where ... instance Fractional Double --where ... instance Floating Double --where ... instance RealFrac Double --where ... instance RealFloat Double --where ... -- The Enum instances for Floats and Doubles are slightly unusual. -- The `toEnum' function truncates numbers to Int. The definitions -- of enumFrom and enumFromThen allow floats to be used in arithmetic -- series: [0,0.1 .. 0.95]. However, roundoff errors make these somewhat -- dubious. This example may have either 10 or 11 elements, depending on -- how 0.1 is represented. instance Enum Float where succ x = x+1 pred x = x-1 toEnum = fromIntegral fromEnum = fromInteger . truncate -- may overflow enumFrom = numericEnumFrom enumFromThen = numericEnumFromThen enumFromTo = numericEnumFromTo enumFromThenTo = numericEnumFromThenTo instance Enum Double where succ x = x+1 pred x = x-1 toEnum = fromIntegral fromEnum = fromInteger . truncate -- may overflow enumFrom = numericEnumFrom enumFromThen = numericEnumFromThen enumFromTo = numericEnumFromTo enumFromThenTo = numericEnumFromThenTo numericEnumFrom :: (Fractional a) => a -> [a] numericEnumFromThen :: (Fractional a) => a -> a -> [a] numericEnumFromTo :: (Fractional a, Ord a) => a -> a -> [a] numericEnumFromThenTo :: (Fractional a, Ord a) => a -> a -> a -> [a] numericEnumFrom = iterate (+1) numericEnumFromThen n m = iterate (+(m-n)) n numericEnumFromTo n m = takeWhile (<= m+1/2) (numericEnumFrom n) numericEnumFromThenTo n n' m = takeWhile p (numericEnumFromThen n n') where p | n' > n = (<= m + (n'-n)/2) | otherwise = (>= m + (n'-n)/2) -- Lists -- This data declaration is not legal Haskell -- but it indicates the idea data [a] = [] | a : [a] deriving (Eq, Ord) --instance Eq a => Eq [a] --instance Ord a => Ord [a] instance Functor [] where fmap = map instance Monad [] where m >>= k = concat (map k m) return x = [x] fail s = [] -- Tuples (supported upto size 15, as required by the Haskell 98 report) data (a,b) = (,) a b deriving (Eq, Ord, Bounded) -- Show/Read in PreludeText, Ix in Ix data (a,b,c) = (,,) a b c deriving (Eq, Ord, Bounded, Show, Read, Ix) data (a,b,c,d) = (,,,) a b c d deriving (Eq, Ord, Bounded, Show, Read) data (a,b,c,d,e) = (,,,,) a b c d e deriving (Eq, Ord, Bounded, Show, Read) data (a,b,c,d,e,f) = (,,,,,) a b c d e f deriving (Eq, Ord, Bounded, Show, Read) data (a,b,c,d,e,f,g) = (,,,,,,) a b c d e f g deriving (Eq, Ord, Bounded, Show, Read) data (a,b,c,d,e,f,g,h) = (,,,,,,,) a b c d e f g h deriving (Eq, Ord, Bounded, Show, Read) data (a,b,c,d,e,f,g,h,i) = (,,,,,,,,) a b c d e f g h i deriving (Eq, Ord, Bounded, Show, Read) data (a,b,c,d,e,f,g,h,i,j) = (,,,,,,,,,) a b c d e f g h i j deriving (Eq, Ord, Bounded, Show, Read) data (a,b,c,d,e,f,g,h,i,j,k) = (,,,,,,,,,,) a b c d e f g h i j k deriving (Eq, Ord, Bounded, Show, Read) data (a,b,c,d,e,f,g,h,i,j,k,l) = (,,,,,,,,,,,) a b c d e f g h i j k l deriving (Eq, Ord, Bounded, Show, Read) data (a,b,c,d,e,f,g,h,i,j,k,l,m) = (,,,,,,,,,,,,) a b c d e f g h i j k l m deriving (Eq, Ord, Bounded, Show, Read) data (a,b,c,d,e,f,g,h,i,j,k,l,m,n) = (,,,,,,,,,,,,,) a b c d e f g h i j k l m n deriving (Eq, Ord, Bounded, Show, Read) data (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) = (,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o deriving (Eq, Ord, Bounded, Show, Read) -- component projections for pairs: -- (NB: not provided for triples, quadruples, etc.) fst :: (a,b) -> a fst (x,y) = x snd :: (a,b) -> b snd (x,y) = y -- curry converts an uncurried function to a curried function; -- uncurry converts a curried function to a function on pairs. curry :: ((a, b) -> c) -> a -> b -> c curry f x y = f (x, y) uncurry :: (a -> b -> c) -> ((a, b) -> c) uncurry f p = f (fst p) (snd p) -- Misc functions -- until p f yields the result of applying f until p holds. until :: (a -> Bool) -> (a -> a) -> a -> a until p f x | p x = x | otherwise = until p f (f x) -- asTypeOf is a type-restricted version of const. It is usually used -- as an infix operator, and its typing forces its first argument -- (which is usually overloaded) to have the same type as the second. asTypeOf :: a -> a -> a asTypeOf = const -- error stops execution and displays an error message error :: String -> a error = primError -- It is expected that compilers will recognize this and insert error -- messages that are more appropriate to the context in which undefined -- appears. undefined :: a undefined = error "Prelude.undefined" {-P: -- For the P-Logic extension: data Prop -}