52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 120

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 120

скобки. Что всё это значит?

Тип-обёртка newtype

Ключевое слово newtype вводит новый тип-обёртку. Тип-обёртка может иметь только один конструктор,

у которого лишь одни аргумент. Запись:

newtype Sum a = Sum a

Это тоже самое, что и

data Sum a = Sum a

Единственное отличие заключается в том, что в случае newtype вычислитель не видит разницы между

Sum a и a. Её видит лишь компилятор. Это означает, что на разворачивание и заворачивание такого значения

в тип обёртку не тратится никаких усилий. Такие типы подходят для решения двух задач:

• Более точная проверка типов.

Например у нас есть типы, которые описывают физические величины, все они являются числами, но у

них также есть и размерности. Мы можем написать:

type Velocity

= Double

type Time

= Double

type Length

= Double

velocity :: Length -> Time -> Velocity

velocity leng time = leng / time

Накопление результата | 113

В этом случае мы спокойно можем подставить на место времени путь и наоборот. Но с помощью типов

обёрток мы можем исключить эти случаи:

newtype Velocity

= Velocity

Double

newtype Time

= Time

Double

newtype Length

= Length

Double

velocity :: Length -> Time -> Velocity

velocity (Length leng) (Time time) = Velocity $ leng / time

В этом случае мы проводим проверку по размерностям, компилятор не допустит смешивания данных.

• Определение нескольких экземпляров одного класса для одного типа. Этот случай мы как раз и рас-

сматриваем для класса Monoid. Нам нужно сделать два экземпляра для одного и того же типа Num a

=> a.

Сделаем две обёртки!

newtype Sum

a = Sum

a

newtype Prod a = Prod a

Тогда мы можем определить два экземпляра для двух разных типов:

Один для Sum:

instance Num a => Monoid (Sum a) where

mempty

= Sum 0

mappend (Sum a) (Sum b) = Sum (a + b)