Россия, Петерубрг, СПБ-ГПУ, 1998 |
Стандартное начало (Prelude)
Заданные по умолчанию определения методов, данные в объявлениях class, составляют спецификацию только заданного по умолчанию метода. Они не составляют спецификацию значения метода во всех экземплярах. Рассмотрим один конкретный пример: заданный по умолчанию метод для enumFrom в классе Enum не будет работать должным образом для типов, чей диапазон превышает диапазон Int (потому что fromEnum не может отображать все значения типа в различные значения Int ).
Показанное здесь Prelude образовано из корневого модуля Prelude и трех подмодулей: PreludeList, PreludeText и PreludeIO. Эта структура является чисто репрезентативной. Реализация не обязана использовать эту организацию для Prelude, также эти три модуля не доступны для импорта по отдельности. Только список экспорта модуля Prelude является значимым.
Некоторые из этих модулей импортируют модули библиотеки, такие как Char, Monad, IO и Numeric. Эти модули полностью описаны в части II. Эти списки импорта, конечно, не являются частью спецификации Prelude. То есть реализация свободна в выборе импортировать больше или меньше модулей библиотеки, по своему усмотрению.
Примитивы, которые не определены на Haskell , обозначаются именами, начинающимися с "prim"; они определены системнозависимым способом в модуле PreludeBuiltin и полностью не показаны. Объявления экземпляров, которые просто связывают примитивы с методами класса, пропущены. Некоторые из наиболее подробных экземпляров с очевидными функциональными возможностями будут пропущены ради краткости.
Объявления специальных типов, таких как Integer или (), включены в Prelude для полноты, даже если объявление может оказаться неполным или синтаксически недопустимым. Пропуски "..." часто используются в местах, где остаток определения не может быть задан на Haskell.
Для того чтобы сократить возникновение неожиданных ошибок неоднозначности и улучшить эффективность, множество общеупотребительных функций над списками чаще используют тип Int, чем более общий числовой тип, такой как Integral a или Num a. Этими функциями являются: take, drop, !!, length, splitAt и replicate. Более общие версии заданы в библиотеке List и имеют приставку "generic", например, genericLength.
module Prelude ( module PreludeList, module PreludeText, module PreludeIO, Bool(False, True), Maybe(Nothing, Just), Either(Left, Right), Ordering(LT, EQ, GT), Char, String, Int, Integer, Float, Double, Rational, IO,
- Эти встроенные типы определены в Prelude, но обозначены встроенным синтаксисом и не могут появляться в списке экспорта.
- Списочный тип: []((:), [])
- Типы кортежей: (,)((,)), (,,)((,,)), etc.
- Тривиальный тип: ()(())
- Функциональный тип: ( )
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 - Содержит все `примитивные' значения import UnicodePrims( primUnicodeMaxChar ) - Примитивы Unicode import PreludeList import PreludeText import PreludeIO import Ratio( Rational ) infixr 9 . infixr 8 ^, ^^, ** infixl 7 *, /, `quot`, `rem`, `div`, `mod` infixl 6 +, -
-Оператор (:) является встроенным синтаксисом и не может быть задан с помощью infix -объявления; но его ассоциативность и приоритет заданы:
infixr 5 : infix 4 ==, /=, <, <=, >=, > infixr 3 && infixr 2 || infixl 1 >>, >>= infixr 1 =<< infixr 0 $, $!, `seq`
- Стандартные типы, классы, экземпляры и относящиеся к ним функции
- Классы равенства (Eq) и упорядочивания (Ordering)
class Eq a where (==), (/=) :: a -> a -> Bool
- Минимальное полное определение:
- (==) 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
- Минимальное полное определение:
- (<=) или compare
-Использование compare может оказаться более эффективным для сложных типов.
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
- обратите внимание, что (min x y, max x y) = (x,y) или (y,x)
max x y | x <= y = y | otherwise = x min x y | x <= y = x | otherwise = y
- Классы перечисления (Enum) и границ (Bounded)
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]
- Минимальное полное определение: - toEnum, fromEnum
- ЗАМЕЧАНИЕ: эти методы по умолчанию только делают вид, - что инъективно отображают типы в Int, используя fromEnum - и 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
- Числовые классы
class (Eq a, Show a) => Num a where (+), (-), (*) :: a -> a -> a negate :: a -> a abs, signum :: a -> a fromInteger :: Integer -> a
- Минимальное полное определение: - Все, за исключением negate или (-)
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
- Минимальное полное определение: - 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
- Минимальное полное определение: - fromRational и (recip или (/))
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
- Минимальное полное определение:
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
- Минимальное полное определение: - 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
- Минимальное полное определение: - Все, за исключением 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 - должен быть после предыдущей проверки y на нуль | x==0 && y==0 = y - должен быть после других двойных проверок на нуль | otherwise = x + y - x или y равен NaN, возвращает NaN (посредством +)