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

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

Possible fix: add an instance declaration for (Num (a0 -> t0))

In the expression: - 2

In the expression: (- 2) 1

In an equation for ‘it’: it = (- 2) 1

Ох уж этот минус. Незадача. Ошибка произошла из-за того, что минус является хамелеоном. Если мы

пишем -2, компилятор воспринимает минус как унарную операцию, и думает, что мы написали константу

минус два. Это сделано для удобства, но иногда это мешает. Это единственное такое исключение в Haskell.

Давайте введём новый синоним для операции минус:

*Nat> let (#) = (-)

*Nat> (2#) 1

1

*Nat> (#2) 1

-1

Эти правила левого и правого применения работают и для буквенных имён в инфиксной форме записи:

*Nat> let minus = (-)

*Nat> (2 ‘minus‘ ) 1

1

*Nat> ( ‘minus‘ 2) 1

-1

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

написать:

... = ... ( ‘fun‘ x) ...

Частичное применение для функций в инфиксной форме записи называют сечением (section), они бывают

соответственно левыми и правыми.

Связь с логикой

Отметим связь основного правила применения с Modus Ponens, известным правилом вывода в логике:

a -> b,

a

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

b

Оно говорит о том, что если у нас есть выражение из a следует b и мы знаем, что a истинно, мы смело

можем утверждать, что b тоже истинно. Если перевести это правило на Haskell, то мы получим: Если у нас

определена функция типа a -> b и у нас есть значение типа a, то мы можем получить значение типа b.

Декомпозиция и сопоставление с образцом

Декомпозиция применяется слева от знака равно, при этом наша задача состоит в том, чтобы опознать

дерево определённого вида и выделить из него некоторые поддеревья. Мы уже пользовались декомпозицией

много раз в предыдущих главах, давайте выпишем примеры декомпозиции:

not :: Bool -> Bool

not True

= ...

not False

= ...

xor :: Bool -> Bool -> Bool

xor a b = ...

show :: Show a => a -> String

show (Time h m s) = ...

addZero :: String -> String

addZero (a:[])

= ...

addZero as