Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π˜Π·ΡƒΡ‡Π°ΠΉ Haskell Π²ΠΎ имя Π΄ΠΎΠ±Ρ€Π°!Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 94

Автор ΠœΠΈΡ€Π°Π½ Π›ΠΈΠΏΠΎΠ²Π°Ρ‡Π°

Π”Π°Π²Π°ΠΉΡ‚Π΅ создадим застёТку для списков. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ фокус Π½Π° подсписках списка, ΠΌΡ‹ пСрСмСщаСмся ΠΈΠ»ΠΈ Π²ΠΏΠ΅Ρ€Ρ‘Π΄, ΠΈΠ»ΠΈ Π½Π°Π·Π°Π΄ (Ρ‚ΠΎΠ³Π΄Π° ΠΊΠ°ΠΊ ΠΏΡ€ΠΈ использовании Π΄Π΅Ρ€Π΅Π²ΡŒΠ΅Π² ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π»ΠΈΡΡŒ Π²Π²Π΅Ρ€Ρ…, Π²Π»Π΅Π²ΠΎ ΠΈΠ»ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ). ΠŸΠΎΠΌΠ΅Ρ‰Ρ‘Π½Π½ΠΎΠΉ Π² фокус Ρ‡Π°ΡΡ‚ΡŒΡŽ Π±ΡƒΠ΄Π΅Ρ‚ подсписок, Π° ΠΊΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ Β«Ρ…Π»Π΅Π±Π½Ρ‹Π΅ ΠΊΡ€ΠΎΡˆΠΊΠΈΒ» ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ нашСго двиТСния Π²ΠΏΠ΅Ρ€Ρ‘Π΄.

А ΠΈΠ· Ρ‡Π΅Π³ΠΎ состояла Π±Ρ‹ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ «хлСбная ΠΊΡ€ΠΎΡˆΠΊΠ°Β» для списка? Когда ΠΌΡ‹ ΠΈΠΌΠ΅Π»ΠΈ Π΄Π΅Π»ΠΎ с Π±ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΌΠΈ Π΄Π΅Ρ€Π΅Π²ΡŒΡΠΌΠΈ, Π½ΡƒΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ «хлСбная ΠΊΡ€ΠΎΡˆΠΊΠ°Β» Ρ…Ρ€Π°Π½ΠΈΠ»Π° элСмСнт, содСрТащийся Π² ΠΊΠΎΡ€Π½Π΅ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ ΡƒΠ·Π»Π°, вмСстС со всСми ΠΏΠΎΠ΄Π΄Π΅Ρ€Π΅Π²ΡŒΡΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ Π½Π΅ Π²Ρ‹Π±Ρ€Π°Π»ΠΈ. Она Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Π»Π° Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Ρ‚ΡŒ, ΠΊΡƒΠ΄Π° ΠΌΡ‹ пошли, – Π²Π»Π΅Π²ΠΎ ΠΈΠ»ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π»ΠΎΡΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π² Π½Π΅ΠΉ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Π»Π°ΡΡŒ вся ΠΈΠΌΠ΅ΡŽΡ‰Π°ΡΡΡ Π² ΡƒΠ·Π»Π΅ информация, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ ΠΏΠΎΠ΄Π΄Π΅Ρ€Π΅Π²Π°, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΡ‹ Ρ€Π΅ΡˆΠΈΠ»ΠΈ навСсти фокус.

Бписки ΠΏΡ€ΠΎΡ‰Π΅, Ρ‡Π΅ΠΌ Π΄Π΅Ρ€Π΅Π²ΡŒΡ. Нам Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Ρ‚ΡŒ, ΠΏΠΎ шли Π»ΠΈ ΠΌΡ‹ Π²Π»Π΅Π²ΠΎ ΠΈΠ»ΠΈ Π²ΠΏΡ€Π°Π²ΠΎ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π²Π³Π»ΡƒΠ±ΡŒ списка ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΉΡ‚ΠΈ лишь ΠΎΠ΄Π½ΠΈΠΌ способом. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡƒΠ·Π»Π° сущСствуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎ ΠΏΠΎΠ΄Π΄Π΅Ρ€Π΅Π²ΠΎ, Π½Π°ΠΌ Ρ‚Π°ΠΊΠΆΠ΅ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Ρ‚ΡŒ ΠΏΡƒΡ‚ΠΈ, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΌΡ‹ Π½Π΅ пошли. ΠšΠ°ΠΆΠ΅Ρ‚ΡΡ, всё, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Ρ‚ΡŒ, – это ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ элСмСнт. Если Ρƒ нас Π΅ΡΡ‚ΡŒ список Π²Ρ€ΠΎΠ΄Π΅ [3,4,5] ΠΈ ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΌ элСмСнтом Π±Ρ‹Π»ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 2, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠΉΡ‚ΠΈ Π½Π°Π·Π°Π΄, просто помСстив этот элСмСнт Π² Β«Π³ΠΎΠ»ΠΎΠ²ΡƒΒ» нашСго списка, получая [2,3,4,5].

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ «хлСбная ΠΊΡ€ΠΎΡˆΠΊΠ°Β» здСсь – просто элСмСнт, Π½Π°ΠΌ Π½Π° самом Π΄Π΅Π»Π΅ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ΅Ρ‰Π°Ρ‚ΡŒ Π΅Ρ‘ Π² Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠ°ΠΊ ΠΌΡ‹ Π΄Π΅Π»Π°Π»ΠΈ это, ΠΊΠΎΠ³Π΄Π° создавали Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… Crumb, использовавшийся застёТками для Π΄Π΅Ρ€Π΅Π²ΡŒΠ΅Π².

type ListZipper a = ([a], [a])

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ список прСдставляСт список, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΌΡ‹ фокусируСмся, Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ – это список Β«Ρ…Π»Π΅Π±Π½Ρ‹Ρ… ΠΊΡ€ΠΎΡˆΠ΅ΠΊΒ». Π”Π°Π²Π°ΠΉΡ‚Π΅ создадим Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π²ΠΏΠ΅Ρ€Ρ‘Π΄ ΠΈ Π½Π°Π·Π°Π΄ ΠΏΠΎ спискам:

goForward :: ListZipper a –> ListZipper a

goForward (x:xs, bs) = (xs, x:bs)


goBack :: ListZipper a –> ListZipper a

goBack (xs, b:bs) = (b:xs, bs)

Когда ΠΌΡ‹ двиТСмся Π²ΠΏΠ΅Ρ€Ρ‘Π΄, ΠΌΡ‹ фокусируСмся Π½Π° «хвостС» Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ списка ΠΈ оставляСм Π³ΠΎΠ»ΠΎΠ²Π½ΠΎΠΉ элСмСнт Π² качСствС Β«Ρ…Π»Π΅Π±Π½ΠΎΠΉ ΠΊΡ€ΠΎΡˆΠΊΠΈΒ». ΠŸΡ€ΠΈ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠΈ Π½Π°Π·Π°Π΄ ΠΌΡ‹ Π±Π΅Ρ€Ρ‘ΠΌ ΡΠ°ΠΌΡƒΡŽ послСднюю Β«Ρ…Π»Π΅Π±Π½ΡƒΡŽ ΠΊΡ€ΠΎΡˆΠΊΡƒΒ» ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π΅Ρ‘ Π² Π½Π°Ρ‡Π°Π»ΠΎ списка. Π’ΠΎΡ‚ эти Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² дСйствии:

ghci> let xs = [1,2,3,4]

ghci> goForward (xs, [])

([2,3,4], [1])

ghci> goForward ([2,3,4], [1])

([3,4], [2,1])

ghci> goForward ([3,4], [2,1])

([4], [3,2,1])

ghci> goBack ([4], [3,2,1])

([3,4], [2,1])

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²ΠΈΠ΄Π΅Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Β«Ρ…Π»Π΅Π±Π½Ρ‹Π΅ ΠΊΡ€ΠΎΡˆΠΊΠΈΒ» Π² случаС со списками – просто пСрСвёрнутая Ρ‡Π°ΡΡ‚ΡŒ вашСго списка. Π­Π»Π΅ΠΌΠ΅Π½Ρ‚, ΠΎΡ‚ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΡ‹ удаляСмся, всСгда помСщаСтся Π² Β«Π³ΠΎΠ»ΠΎΠ²ΡƒΒ» Β«Ρ…Π»Π΅Π±Π½Ρ‹Ρ… ΠΊΡ€ΠΎΡˆΠ΅ΠΊΒ». ΠŸΠΎΡ‚ΠΎΠΌ Π»Π΅Π³ΠΊΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒΡΡ Π½Π°Π·Π°Π΄, просто вынимая этот элСмСнт ΠΈΠ· ΠΈΡ… Β«Π³ΠΎΠ»ΠΎΠ²Ρ‹Β» ΠΈ дСлая Π΅Π³ΠΎ Β«Π³ΠΎΠ»ΠΎΠ²ΠΎΠΉΒ» нашСго фокуса. На Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΎΠΏΡΡ‚ΡŒ-Ρ‚Π°ΠΊΠΈ Π»Π΅Π³ΠΊΠΎ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ ΠΌΡ‹ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌ это застёТкой: Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΎΡ‡Π΅Π½ΡŒ Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°ΡŽΡ‰ΠΈΠΉΡΡ Π²Π²Π΅Ρ€Ρ…-Π²Π½ΠΈΠ· Π·Π°ΠΌΠΎΠΊ застёТки-ΠΌΠΎΠ»Π½ΠΈΠΈ!

Если Π±Ρ‹ Π²Ρ‹ создавали тСкстовый Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€, ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ список строк для прСдставлСния строк тСкста, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π² Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ застёТку, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π½Π°Ρ‚ΡŒ, Π½Π° ΠΊΠ°ΠΊΠΎΠΉ строкС Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ установлСн курсор. ИспользованиС застёТки Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΠ±Π»Π΅Π³Ρ‡ΠΈΠ»ΠΎ Π±Ρ‹ вставку Π½ΠΎΠ²Ρ‹Ρ… строк Π² любом мСстС тСкста ΠΈΠ»ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ…ΡΡ строк.

ΠžΡ‡Π΅Π½ΡŒ простая файловая систСма

Для дСмонстрации Ρ€Π°Π±ΠΎΡ‚Ρ‹ застёТСк Π΄Π°Π²Π°ΠΉΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π΄Π΅Ρ€Π΅Π²ΡŒΡ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΎΡ‡Π΅Π½ΡŒ ΠΏΡ€ΠΎΡΡ‚ΡƒΡŽ Ρ„Π°ΠΉΠ»ΠΎΠ²ΡƒΡŽ систСму. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ застёТку для этой Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмы, которая ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ Π½Π°ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒΡΡ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°ΠΌΠΈ, ΠΊΠ°ΠΊ ΠΌΡ‹ это Π΄Π΅Π»Π°Π΅ΠΌ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Π°Ρ… ΠΏΠΎ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΉ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС.

ΠžΠ±Ρ‹Ρ‡Π½Π°Ρ иСрархичСская файловая систСма состоит прСимущСствСнно ΠΈΠ· Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ². Π€Π°ΠΉΠ»Ρ‹ – это элСмСнты Π΄Π°Π½Π½Ρ‹Ρ…, снабТённыС ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ. ΠšΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ этих Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ. Для нашСго простого ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° достаточно ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ элСмСнтами Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмы ΡΠ²Π»ΡΡŽΡ‚ΡΡ:

β€’ Ρ„Π°ΠΉΠ» ΠΏΠΎΠ΄ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ, содСрТащий Π½Π΅ΠΊΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Π΅;

β€’ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ ΠΏΠΎΠ΄ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ, содСрТащий Π΄Ρ€ΡƒΠ³ΠΈΠ΅ элСмСнты, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ сами ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΈΠ»ΠΈ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ, ΠΈΠ»ΠΈ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°ΠΌΠΈ.

Π’ΠΎΡ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ синонимы Ρ‚ΠΈΠΏΠΎΠ², Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Π»ΠΎ понятно, Ρ‡Ρ‚ΠΎ ΠΊ Ρ‡Π΅ΠΌΡƒ:

type Name = String

type Data = String

data FSItem = File Name Data | Folder Name [FSItem] deriving (Show)

К Ρ„Π°ΠΉΠ»Ρƒ ΠΏΡ€ΠΈΠ»Π°Π³Π°ΡŽΡ‚ΡΡ Π΄Π²Π΅ строки, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅ Π΅Π³ΠΎ имя ΠΈ содСрТимоС. К ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Ρƒ ΠΏΡ€ΠΈΠ»Π°Π³Π°ΡŽΡ‚ΡΡ строка, ΡΠ²Π»ΡΡŽΡ‰Π°ΡΡΡ Π΅Π³ΠΎ ΠΈΠΌΠ΅Π½Π΅ΠΌ, ΠΈ список элСмСнтов. Если этот список пуст, Π·Π½Π°Ρ‡ΠΈΡ‚, ΠΌΡ‹ ΠΈΠΌΠ΅Π΅ΠΌ пустой ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³.

Π’ΠΎΡ‚ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ ΠΈ ΠΏΠΎΠ΄ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°ΠΌΠΈ (Π½Π° самом Π΄Π΅Π»Π΅ это Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π² Π½Π°ΡΡ‚ΠΎΡΡ‰ΡƒΡŽ ΠΌΠΈΠ½ΡƒΡ‚Ρƒ содСрТится Π½Π° ΠΌΠΎΡ‘ΠΌ дискС):

myDisk :: FSItem

myDisk =

   Folder "root"

      [ File "goat_yelling_like_man.wmv" "Π±Π°Π°Π°Π°Π°Π°Π°"

      , File "pope_time.avi" "Π‘ΠΎΠΆΠ΅, благослови"

      , Folder "pics"

        [ File "ape_throwing_up.jpg" "Π±Π»ΠΈΠ½..."

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

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

        ]

      , File "dijon_poupon.doc" "Π»ΡƒΡ‡ΡˆΠ°Ρ Π³ΠΎΡ€Ρ‡ΠΈΡ†Π°"

      , Folder "programs"

        [ File "sleepwizard.exe" "10 ΠΏΠΎΠΉΡ‚ΠΈ ΠΏΠΎΡΠΏΠ°Ρ‚ΡŒ"

        , File "owl_bandit.dmg" "move ax, 42h"

        , File "not_a_virus.exe" "Ρ‚ΠΎΡ‡Π½ΠΎ Π½Π΅ вирус"

        , Folder "source code"

           [ File "best_hs_prog.hs" "main = print (fix error)"

           , File "random.hs" "main = print 4"

           ]

        ]

      ]

Π‘ΠΎΠ·Π΄Π°Ρ‘ΠΌ застёТку для нашСй Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмы


Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° Ρƒ нас Π΅ΡΡ‚ΡŒ файловая систСма, всё, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ, – это застёТка, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π·Π°ΡΡ‚Ρ‘Π³ΠΈΠ²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ»ΠΎΠ²ΡƒΡŽ систСму ΠΈ Π±Ρ€Π°Ρ‚ΡŒ Π΅Ρ‘ ΠΊΡ€ΡƒΠΏΠ½Ρ‹ΠΌ ΠΏΠ»Π°Π½ΠΎΠΌ, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ, ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΈ ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ. Как ΠΈ Π² случаС с использованиСм Π±ΠΈΠ½Π°Ρ€Π½Ρ‹Ρ… Π΄Π΅Ρ€Π΅Π²ΡŒΠ΅Π² ΠΈ списков, наши Β«Ρ…Π»Π΅Π±Π½Ρ‹Π΅ ΠΊΡ€ΠΎΡˆΠΊΠΈΒ» Π±ΡƒΠ΄ΡƒΡ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΠ±ΠΎ всём, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Ρ€Π΅ΡˆΠΈΠ»ΠΈ Π½Π΅ ΠΏΠΎΡΠ΅Ρ‰Π°Ρ‚ΡŒ. ΠžΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ «хлСбная ΠΊΡ€ΠΎΡˆΠΊΠ°Β» Π΄ΠΎΠ»ΠΆΠ½Π° Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ всё, ΠΊΡ€ΠΎΠΌΠ΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€Π΅Π²Π°, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΌΡ‹ фокусируСмся Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚. Она Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ½Π° ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ, Π³Π΄Π΅ находится отвСрстиС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π²Π²Π΅Ρ€Ρ… ΠΌΡ‹ смогли Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π² отвСрстиС наш ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ фокус.

Π’ этом случаС «хлСбная ΠΊΡ€ΠΎΡˆΠΊΠ°Β» Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΡ…ΠΎΠΆΠ° Π½Π° ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ – Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Ρ‹Π±Ρ€Π°Π½Π½Ρ‹ΠΉ Π½Π°ΠΌΠΈ Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π² Π½Ρ‘ΠΌ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ. Π’Ρ‹ спроситС: «А ΠΏΠΎΡ‡Π΅ΠΌΡƒ Π½Π΅ Π½Π° Ρ„Π°ΠΉΠ»?Β» Ну, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ фокусируСмся Π½Π° Ρ„Π°ΠΉΠ»Π΅, ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡƒΠ³Π»ΡƒΠ±Π»ΡΡ‚ΡŒΡΡ Π² Ρ„Π°ΠΉΠ»ΠΎΠ²ΡƒΡŽ систСму, Π° Π·Π½Π°Ρ‡ΠΈΡ‚, Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ смысла ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ Β«Ρ…Π»Π΅Π±Π½ΡƒΡŽ ΠΊΡ€ΠΎΡˆΠΊΡƒΒ», которая Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΏΡ€ΠΈΡˆΠ»ΠΈ ΠΈΠ· Ρ„Π°ΠΉΠ»Π°. Π€Π°ΠΉΠ» – это Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π²Ρ€ΠΎΠ΄Π΅ пустого Π΄Π΅Ρ€Π΅Π²Π°.

Если ΠΌΡ‹ фокусируСмся Π½Π° ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅ "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, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ фокусируСтся Π½Π° Ρ„Π°ΠΉΠ»Π΅ с Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ. Π­Ρ‚ΠΎΡ‚ Ρ„Π°ΠΉΠ» Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅, находящСмся Π² фокусС. Данная функция Π½Π΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ поиск Π²Π΅Π·Π΄Π΅ – ΠΎΠ½Π° просто смотрит Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅.