Опубликован: 19.09.2008 | Доступ: свободный | Студентов: 658 / 70 | Оценка: 4.50 / 5.00 | Длительность: 21:25:00
Лекция 9:

Стандартное начало (Prelude)

- Стандартные числовые типы. Объявления данных для этих типов нельзя - выразить непосредственно на Haskell, т.к. конструируемые списки были бы - слишком длинными.

data  Int  =  minBound ... -1 | 0 | 1 ... maxBound

instance  Eq       Int  where ...

instance  Ord      Int  where ...

instance  Num      Int  where ...

instance  Real     Int  where ...

instance  Integral Int  where ...

instance  Enum     Int  where ...

instance  Bounded  Int  where ...


data  Integer  =  ... -1 | 0 | 1 ...

instance  Eq       Integer  where ...

instance  Ord      Integer  where ...

instance  Num      Integer  where ...

instance  Real     Integer  where ...

instance  Integral Integer  where ...

instance  Enum     Integer  where ...


data  Float

instance  Eq         Float  where ...

instance  Ord        Float  where ...

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 ...

instance  Ord        Double  where ...

instance  Num        Double  where ...

instance  Real       Double  where ...

instance  Fractional Double  where ...

instance  Floating   Double  where ...

instance  RealFrac   Double  where ...

instance  RealFloat  Double  where ...

- Экземпляры Enum для Float и Double слегка необычны. - Функция 'toEnum' выполняет усечение числа до Int. Определения - enumFrom и enumFromThen позволяют использовать числа с плавающей точкой в арифметических - последовательностях: [0,0.1 .. 0.95]. Тем не менее, ошибки roundoff делают это несколько - сомнительным. В этом примере может быть 10 или 11 элементов, в зависимости от того, - как представлено 0.1.

instance  Enum Float  where
    succ x           =  x+1
    pred x           =  x-1
    toEnum           =  fromIntegral
    fromEnum         =  fromInteger . truncate   -

может вызвать переполнение

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   -

может вызвать переполнение

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)

- Списки

data  [a]  =  [] | a : [a]  deriving (Eq, Ord)

- Недопустимо в Haskell; только для примера

instance Functor [] where
    fmap = map


instance  Monad []  where
    m >>= k          = concat (map k m)
    return x         = [x]
    fail s           = []

- Кортежи

data  (a,b)   =  (a,b)    deriving (Eq, Ord, Bounded)

data  (a,b,c) =  (a,b,c)  deriving (Eq, Ord, Bounded)

- Недопустимо в Haskell; только для примера - проекции компонент для пары: - (NB: не предусмотрено для кортежей размера 3, 4 и т.д.)

fst              :: (a,b) -> a
fst (x,y)        =  x


snd              :: (a,b) -> b
snd (x,y)        =  y

- curry преобразует развернутую функцию (функцию двух аргументов) в свернутую функцию (функцию над парой аргументов) - uncurry преобразует свернутую функцию в развернутую функцию

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)

- Разные функции

- until p f получает результат применения f до тех пор, пока p выполняется.


until            :: (a -> Bool) -> (a -> a) -> a -> a
until p f x 
     | p x       =  x
     | otherwise =  until p f (f x)

- asTypeOf является версией const с ограниченным набором типов. Она обычно используется - в качестве инфиксного оператора, и ее типизация приводит к тому, что ее первый аргумент - (который обычно является перегруженным) должен иметь тот же тип, что второй аргумент.

asTypeOf         :: a -> a -> a
asTypeOf         =  const

- error останавливает вычисление и выводит на экран сообщение об ошибке

error            :: String -> a
error            =  primError

- Ожидается, что компиляторы распознают это и вставят - более подходящие сообщения об ошибках для контекста, в котором возник undefined.

undefined        :: a
undefined        =  error "Prelude.undefined"