Читаем Изучай Haskell во имя добра! полностью

Она говорит, что функция принимает список пар со значениями типа k и v и возвращает отображение, которое отображает ключи типа k в значения типа v. Обратите внимание, что если мы реализуем ассоциативный список с помощью обычного списка, то значения ключей должны лишь уметь сравниваться (иметь экземпляр класса типов Eq); теперь же должна быть возможность их упорядочить (класс типов Ord). Это существенное ограничение модуля Data.Map. Упорядочиваемые ключи нужны ему для того, чтобы размещать данные более эффективно.

Теперь мы можем преобразовать наш исходный ассоциативный список phoneBook в отображение. Заодно добавим сигнатуру:

import qualified Data.Map as Map

phoneBook :: Map.Map String String

phoneBook = Map.fromList $

  [("оля","555–29-38")

  ,("женя","452–29-28")

  ,("катя","493–29-28")

  ,("маша","205–29-28")

  ,("надя","939–82-82")

  ,("юля","853–24-92")

  ]

Отлично. Загрузим этот сценарий в GHCi и немного поиграем с телефонной книжкой. Во-первых, воспользуемся функцией lookup и поищем какие-нибудь номера. Функция lookup принимает ключ и отображение и пытается найти соответствующее ключу значение. Если всё прошло удачно, возвращается обёрнутое в Just значение; в противном случае – Nothing:

ghci> :t Map.lookup

Map.lookup :: (Ord k) => k -> Map.Map k a -> Maybe a

ghci> Map.lookup "оля" phoneBook

Just "555-29-38"

ghci> Map.lookup "надя" phoneBook

Just "939-82-82"

ghci> Map.lookup "таня" phoneBook

Nothing

Следующий трюк: создадим новое отображение, добавив в исходное новый номер. Функция insert принимает ключ, значение и отображение и возвращает новое отображение – почти такое же, что и исходное, но с добавленными ключом и значением:

ghci> :t Map.insert

Map.insert :: (Ord k) => k -> a -> Map.Map k a -> Map.Map k a

ghci> Map.lookup "таня" phoneBook

Nothing

ghci> let newBook = Map.insert "таня" "341-90-21" phoneBook

ghci> Map.lookup "таня" newBook

Just "341-90-21"

Давайте посчитаем, сколько у нас телефонных номеров. Для этого нам понадобится функция size из модуля Data.Map. Она принимает отображение и возвращает его размер. Тут всё ясно:

ghci> :t Map.size

Map.size :: Map.Map k a -> Int

ghci> Map.size phoneBook

6

ghci> Map.size newBook

7

Номера в нашей телефонной книжке представлены строками. Допустим, мы хотим вместо них использовать списки цифр: то есть вместо номера "939-82-82" – список [9,3,9,8,2,8,2]. Сначала напишем функцию, конвертирующую телефонный номер в строке в список целых. Можно попытаться применить функцию digitToInt из модуля Data.Char к каждому символу в строке, но она не знает, что делать с дефисом! Поэтому нужно избавиться от всех нецифр. Попросим помощи у функции isDigit из модуля Data.Char, которая принимает символ и сообщает нам, является ли он цифрой. Как только строка будет отфильтрована, пройдёмся по ней функцией digitToInt.

string2digits :: String -> [Int]

string2digits = map digitToInt . filter isDigit

Да, не забудьте импортировать модуль Data.Char. Пробуем:

ghci> string2digits "948-92-82"

[9,4,8,9,2,8,2]

Замечательно! Теперь применим функцию map из модуля Data. Map, чтобы пропустить функцию string2digits по элементам отображения phoneBook:

ghci> let intBook = Map.Map string2digits phoneBook

ghci> :t intBook

intBook :: Map.Map String [Int]

ghci> Map.lookup "оля" intBook

Just [5,5,5,2,9,3,8]

Функция map из модуля Data.Map принимает функцию и отображение и применяет эту функцию к каждому значению в отображении.

Расширим телефонную книжку. Предположим, что у кого-нибудь есть несколько телефонных номеров, и наш ассоциативный список выглядит как-то так:

phoneBook =

  [("оля","555–29-38")

  ,("оля","342–24-92")

  ,("женя","452–29-28")

  ,("катя","493–29-28")

  ,("катя","943–29-29")

  ,("катя","827–91-62")

  ,("маша","205–29-28")

  ,("надя","939–82-82")

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных