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

Как насчёт продвижения вглубь файловой системы? Если мы находимся в "root" и хотим сфокусироваться на файле "dijon_poupon. doc", оставляемая нами «хлебная крошка» будет включать имя "root" вместе с элементами, предшествующими файлу "dijon_poupon.doc", и элементами, идущими за ним. Вот функция, которая, получив имя, фокусируется на файле или каталоге, расположенном в текущем каталоге, куда в текущий момент наведён фокус:

import Data.List (break)

fsTo :: Name –> FSZipper –> FSZipper

fsTo name (Folder folderName items, bs) =

   let (ls, item:rs) = break (nameIs name) items

   in (item, FSCrumb folderName ls rs:bs)

nameIs :: Name –> FSItem –> Bool

nameIs name (Folder folderName _) = name == folderName

nameIs name (File fileName _) = name == fileName

Функция fsTo принимает значения Name и FSZipper и возвращает новое значение FSZipper, которое фокусируется на файле с заданным именем. Этот файл должен присутствовать в текущем каталоге, находящемся в фокусе. Данная функция не производит поиск везде – она просто смотрит в текущем каталоге.

Сначала мы используем функцию break, чтобы разбить список элементов в каталоге на те, что предшествуют искомому нами файлу, и те, что идут за ним. Функция break принимает предикат и список и возвращает пару списков. Первый список в паре содержит элементы, для которых предикат возвращает значение False. Затем, когда предикат возвращает значение True для элемента, функция помещает этот элемент и остальную часть списка во второй элемент пары. Мы создали вспомогательную функцию nameIs, которая принимает имя и элемент файловой системы и, если имена совпадают, возвращает значение True.

Теперь ls – список, содержащий элементы, предшествующие искомому нами элементу; item является этим самым элементом, а rs – это список элементов, идущих за ним в его каталоге. И вот сейчас, когда они у нас есть, мы просто представляем элемент, полученный нами из функции break, как фокус и строим «хлебную крошку», которая содержит все необходимые ей данные.

Обратите внимание, что если имя, которое мы ищем, не присутствует в каталоге, образец item:rs попытается произвести сопоставление с пустым списком, и мы получим ошибку. А если наш текущий фокус – файл, а не каталог, мы тоже получим ошибку, и программа завершится аварийно.

Итак, мы можем двигаться вверх и вниз по нашей файловой системе. Давайте начнём движение с корня и перейдём к файлу "skull_man(scary).bmp":

ghci> let newFocus = (myDisk, []) -: fsTo "pics" -: fsTo "skull_man(scary).bmp"

Значение newFocus теперь – застёжка, сфокусированная на файле skull_man(scary).bmp. Давайте получим первый компонент застёжки (сам фокус) и посмотрим, так ли это на самом деле.

ghci> fst newFocus

File "skull_man(scary).bmp" "Ой!"

Переместимся выше и сфокусируемся на соседнем с ним файле "watermelon_smash.gif":

ghci> let newFocus2 = newFocus –: fsUp –: fsTo "watermelon_smash.gif"

ghci> fst newFocus2

File "watermelon_smash.gif" "шмяк!!"

<p>Манипулируем файловой системой</p>

Теперь, когда мы можем передвигаться по нашей файловой системе, ею легко манипулировать. Вот функция, которая переименовывает находящийся в данный момент в фокусе файл или каталог:

fsRename :: Name –> FSZipper –> FSZipper

fsRename newName (Folder name items, bs) = (Folder newName items, bs)

fsRename newName (File name dat, bs) = (File newName dat, bs)

Давайте переименуем наш каталог "pics" в "cspi":

ghci> let newFocus = (myDisk, []) –: fsTo "pics" –: fsRename "cspi" –: fsUp

Мы спустились к каталогу "pics", переименовали его, а затем поднялись обратно вверх.

Как насчёт функции, которая создаёт новый элемент в текущем каталоге? Встречайте:

fsNewFile :: FSItem –> FSZipper –> FSZipper

fsNewFile item (Folder folderName items, bs) =

   (Folder folderName (item:items), bs)

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

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

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

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

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

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

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

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

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

Все жанры