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

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

-------------------------------------------------------------

(Succ Zero) :: Bool

Воспользовавшись правилом применения мы узнали, что тип выражения Succ Zero должен быть равен

Bool. Проверим, так ли это?

(Succ Zero) - ?

Succ :: Nat -> Nat,

Zero :: Nat

----------------------------------------------------------

f x, f = Succ, x = Zero следовательно (f x) :: Nat

----------------------------------------------------------

(Succ Zero) :: Nat

Из этой цепочки следует, что (Succ Zero) имеет тип Nat. Мы пришли к противоречию и сообщаем об

этом пользователю.

< interactive>:1:5:

Не могу сопоставить ожидаемый тип ’Bool’ с выведенным ’Nat’

В типе результата вызова Succ’

В первом аргументе ‘not’, а именно ‘(Succ Zero)’

В выражении: not (Succ Zero)

Потренируйтесь в составлении неправильных выражений и посмотрите почему они не правильные. Мыс-

ленно сверьтесь с правилом применения в каждом из слагаемых.

Специализация типов при подстановке

Мы говорили о том, что тип аргумента функции и тип подставляемого значения должны совпадать, но

на самом деле есть и другая возможность. Тип аргумента или тип значения могут быть полиморфными. В

этом случае происходит специализация общего типа. Например, при выполнении выражения:

*Nat> Succ Zero + Zero

Succ (Succ Zero)

Происходит специализация общей функции (+) :: Num a => a -> a -> a до функции (+) :: Nat ->

Nat -> Nat, которая определена в экземпляре Num для Nat.

Проверка типов с контекстом

Предположим, что у функции f есть контекст, который говорит о том, что первый аргумент принадлежит

некоторому классу f :: C a => a -> b, тогда значение, которое мы подставляем в функцию, должно быть

экземпляром класса C.

Для иллюстрации давайте попробуем сложить логические значения:

*Nat Prelude> True + False

< interactive>:11:6:

No instance for (Num Bool)

arising from a use of +

Possible fix: add an instance declaration for (Num Bool)

In the expression: True + False

In an equation for ‘it’: it = True + False

Компилятор говорит о том, что для типа Bool не

определён экземпляр для класса Num.

Проверка типов | 51

No instance for (Num Bool)

Запишем это в виде правила:

f :: C a => a -> b,

x :: T, instance C T

-----------------------------------------

(f x) :: b

Важно отметить, что x имеет конкретный тип T. Если x – значение, у которого тип с параметром, компиля-