>ghci> Map.fromList [("MS",1),("MS",2),("MS",3)]
>fromList [("MS",3)]
Вот сигнатура функции >fromList
:
>Map.fromList :: (Ord k) => [(k, v)] –> Map.Map k v
Она говорит, что функция принимает список пар со значениями типа >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]
. Сначала напишем функцию, конвертирующую телефонный номер в строке в список целых. Можно попытаться применить функцию