Изучай Haskell во имя добра! (Липовача) - страница 85

Автомобиль теперь создаётся и отображается следующим образом:

>ghci> Car {company="Форд", model="Мустанг", year=1967}

>Car {company = "Форд", model = "Мустанг", year = 1967}

При создании нового автомобиля мы, разумеется, обязаны перечислить все поля, но указывать их можно в любом порядке. Но если мы не используем синтаксис записей с именованными полями, то должны указывать их по порядку.

Используйте синтаксис записей с именованными полями, если конструктор имеет несколько полей и не очевидно, какое поле для чего используется. Если, скажем, мы создаём трёхмерный вектор: >data Vector = Vector Int Int Int, то вполне понятно, что поля конструктора данных – это компоненты вектора. Но в типах >Person и >Car назначение полей совсем не так очевидно, и мы значительно выиграем, используя синтаксис записей с именованными полями.

Параметры типа

Конструктор данных может принимать несколько параметров-значений и возвращать новое значение. Например, конструктор >Car принимает три значения и возвращает одно – экземпляр типа >Car. Таким же образом конструкторы типа могут принимать типы-параметры и создавать новые типы. На первый взгляд это несколько абстрактно, но на самом деле не так уж сложно. Если вы знакомы с шаблонами в языке С++, то увидите некоторые параллели. Чтобы получить более ясное представление о том, как работают типы-параметры, давайте посмотрим, как реализованы типы, с которыми мы уже встречались.

>data Maybe a = Nothing | Just a



В данном примере идентификатор >a – тип-параметр (переменная типа, типовая переменная). Так как в выражении присутствует тип-параметр, мы называем идентификатор >Maybe конструктором типов. В зависимости от того, какой тип данных мы хотим сохранять в типе >Maybe, когда он не >Nothing, конструктор типа может производить такие типы, как >Maybe Int, >Maybe Car, >Maybe String и т. д. Ни одно значение не может иметь тип «просто >Maybe», потому что это не тип как таковой – это конструктор типов. Для того чтобы он стал настоящим типом, значения которого можно создать, мы должны указать все типы-параметры в конструкторе типа.

Итак, если мы передадим тип >Char как параметр в тип >Maybe, то получим тип >Maybe Char. Для примера: значение >Just 'a' имеет тип >Maybe Char.

Обычно нам не приходится явно передавать параметры конструкторам типов, поскольку в языке Haskell есть вывод типов. Поэтому когда мы создаём значение >Just 'a', Haskell тут же определяет его тип – >Maybe Char.

Если мы всё же хотим явно указать тип как параметр, это нужно делать в типовой части выражений, то есть после символа