Учебник по Haskell | страница 28



ходит. Оно не верно как раз из-за нарушения свойств. Для группы необходимо, чтобы для любого a выпол-

нялось:

inv a + a == e

У нас лишь два значения, и это свойство не выполняется ни для одного из них. Проверим:

inv True

+ True

=> (not True) + True

=> False

+ True

=> and False

True

=> False

inv False

+ False

=> (not False) + False

=> True

+ False

=> and True

False

=> False

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

будут на них рассчитывать.

20 | Глава 1: Основы

1.6 Ядро Haskell

Фуууухх. Мы закончили наш пробег. Теперь можно остановиться, отдышаться и подвести итоги. Давайте

вспомним синтаксические конструкции, которые нам встретились.

Модули

module New(edef1, edef2, ... , edefN) where

import Old1(idef11, idef12, ... , idef1N)

import Old2(idef21, idef22, ... , idef2M)

...

import OldK(idefK1, idefK2, ... , idefKP)

-- определения :

...

Ключевые слова: module, where, import. Мы определили модуль с именем New, который экспортирует

определения edef1, edef2, … , edefN. И импортирует определения из модулей Old1, Old2, и т.д., определения

написаны в скобках за ключевыми словами import и именами модулей.

Типы

Тип определяется с помощью:

• Перечисления альтернатив через |

data Type = Alt1 | Alt2 | ... | AltN

Эту операцию называют суммой типов.

• Составления сложного типа из подтипов, пишем конструктор первым, затем через пробел подтипы:

data Type = Name

Sub1

Sub2

...

SubN

Эту операцию называют произведением типов.

Есть одно исключение: если тип состоит из двух подтипов, мы можем дать конструктору символьное

(а не буквенное) имя, но оно должно начинаться с двоеточия :, как в случае списка, например, можно

делать такие определения типов:

data Type = Sub1 :+ Sub2

data Type = Sub1 :| Sub2

• Комбинации суммы и произведения типов:

data Type = Name1

Sub11

Sub12

...

Sub1N

| Name2

Sub21

Sub22

...

Sub2M

...

| NameK

SubK1

SubK2

...

SubKP

Такие типы называют алгебраическими типами данных. С помощью типов мы определяем основные поня-

тия и способы их комбинирования.

Значения

Как это ни странно, нам встретилась лишь одна операция создания значений: определение синонима. Она

пишется так

name x1

x2 ... xN = Expr1

name x1

x2 ... xN = Expr2

name x1

x2 ... xN = Expr3

Слева от знака равно стоит составное имя, а справа от знака равно некоторое выражение, построенное

согласно типам. Разные комбинации имени name с параметрами определяют разные уравнения для синонима

name.

Также мы видели символ _, который означает “всё, что угодно” на месте аргумента. А также мы увидели,