52700.fb2
(*) a (Succ b) = a + (a * b)
fromInteger 0 = Zero
fromInteger n = Succ (fromInteger (n-1))
abs
x
= x
signum Zero = Zero
signum _
= Succ Zero
negate _ = error ”negate is undefined for Nat”
34 | Глава 2: Первая программа
Класс Fractional. Деление
Деление определено в классе Fractional:
*Nat>:m Prelude
Prelude> :i Fractional
class Num a => Fractional a where
(/) :: a -> a -> a
recip :: a -> a
fromRational :: Rational -> a
-- Defined in ‘GHC.Real’
instance Fractional Float -- Defined in ‘GHC.Float’
instance Fractional Double -- Defined in ‘GHC.Float’
Функция recip, это аналог negate для Num. Она делит единицу на данное число. Функция fromRational
строит число данного типа из дробного числа. Если мы пишем 2, то к нему подспудно будет применена
функция fromInteger, а если 2.0, то будет применена функция fromRational.
Стандартные числа
В этом подразделе мы рассмотрим несколько стандартных типов для чисел в Haskell. Все эти числа явля-
ются экземплярами основных численных классов. Тех, которые мы рассмотрели, и многих-многих других.
Целые числа
В Haskell предусмотрено два типа для целых чисел. Это Integer и Int. Чем они отличаются? Значения
типа Integer не ограничены, мы можем проводить вычисления с очень-очень-очень большими числами, если
памяти на нашем компьютере хватит. Числа из типа Int ограничены. Каждое число занимает определённый
размер в памяти компьютера. Диапазон значений для Int составляет от − 229 до 229 − 1. Вычисления с Int
более эффективны.
Действительные числа
Действительные числа бывают дробными (тип Rational), с ординарной точностью Float и с двойной
точностью Double. Числа из типа Float занимают меньше места, но они не такие точные как Double. Если вы
сомневаетесь, чем пользоваться, выбирайте Double, обычно Float используется только там, где необходимо
хранить огромные массивы чисел. В этом случае мы экономим много памяти.
Преобразование численных типов
Во многих языках программирования при сложении или умножении чисел разных типов проводится ав-
томатическое приведение типов. Обычно целые числа становятся действительными, Float превращается в
Double и так далее. Это противоречит строгой типизации, поэтому в Haskell этого нет:
Prelude> (1::Int) + (1::Double)
< interactive>:2:13:
Couldn’t match expected type ‘Int’ with actual type ‘Double’
In the second argument of ‘(+)’, namely ‘(1 :: Double)’
In the expression: (1 :: Int) + (1 :: Double)
In an equation for ‘it’: it = (1 :: Int) + (1 :: Double)