Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Создаём застёжку для нашей файловой системыСодержание книги
Поиск на нашем сайте
Теперь, когда у нас есть файло- вая система, всё, что нам нуж- но, – это застёжка, чтобы мы могли застёгивать файловую систему и брать её крупным пла- ном, а также добавлять, изме- нять и удалять файлы и каталоги. Как и в случае с использовани- ем бинарных деревьев и спис- ков, наши «хлебные крошки» будут содержать информацию обо всём, что мы решили не посещать. Отдельная «хлебная крошка» должна хранить всё, кроме поддерева, на котором мы фокусируемся в данный момент. Она также должна указывать, где находится отверстие, чтобы при перемещении обратно вверх мы смогли вставить в отверстие наш предыдущий фокус. В этом случае «хлебная крошка» должна быть похожа на ката- лог – только выбранный нами в данный момент каталог должен в нём отсутствовать. Вы спросите: «А почему не на файл?» Ну, пото- му что, когда мы фокусируемся на файле, мы не можем углубляться в файловую систему, а значит, не имеет смысла оставлять «хлебную крошку», которая говорит, что мы пришли из файла. Файл – это что-то вроде пустого дерева. Если мы фокусируемся на каталоге "root", а затем на файле "dijon_poupon.doc", как должна выглядеть «хлебная крошка», кото- рую мы оставляем? Она должна содержать имя своего родитель- ского каталога вместе с элементами, идущими перед файлом, на котором мы фокусируемся, и следом за ним. Поэтому всё, что нам
требуется, – значение Name и два списка элементов. Храня два отде- льных списка для элементов, идущих перед элементом, на котором мы фокусируемся, и для элементов, идущих за ним, мы будем точно знать, где мы его поместили, при перемещении обратно вверх. Та- ким образом, нам известно местоположение отверстия. Вот наш тип «хлебной крошки» для файловой системы: data FSCrumb = FSCrumb Name [FSItem] [FSItem] deriving (Show) А вот синоним типа для нашей застёжки: type FSZipper = (FSItem, [FSCrumb]) Идти обратно вверх по иерархии очень просто. Мы берём самую последнюю «хлебную крошку» и собираем новый фокус из текущего фокуса и «хлебной крошки» следующим образом: fsUp:: FSZipper –> FSZipper fsUp (item, FSCrumb name ls rs:bs) = (Folder name (ls ++ [item] ++ rs), bs) Поскольку нашей «хлебной крошке» были известны имя роди- тельского каталога, а также элементы, которые шли перед находя- щимся в фокусе элементом каталога (то есть ls), и элементы, кото- рые шли за ним (то есть rs), перемещаться вверх было легко. Как насчёт продвижения вглубь файловой системы? Если мы на- ходимся в "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" "шмяк!!"
|
|||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2017-02-17; просмотров: 208; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.119.117.77 (0.007 с.) |