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

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

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

Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ, ΠΊΠ°ΠΊ это достигаСтся, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ просто ΠΏΡ€ΠΎΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ Π·Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ. Π‘Π½Π°Ρ‡Π°Π»Π° Ρƒ нас Π΅ΡΡ‚ΡŒ список [3,4,5]. ΠŸΠΎΡ‚ΠΎΠΌ ΠΌΡ‹ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌ Π΅Π³ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

[[3,-3],[4,-4],[5,-5]]

Анонимная функция примСняСтся ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ элСмСнту, ΠΈ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ список списков. Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΠΌΡ‹ просто сглаТиваСм список – ΠΈ вуаля, ΠΌΡ‹ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠ»ΠΈ Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΊ Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ!

ΠΠ΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ Π½Π΅ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹Ρ… вычислСний. ΠŸΡƒΡΡ‚ΠΎΠΉ список Π² Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ стСпСни эквивалСнтСн Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ Nothing, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ½ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ отсутствиС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°. Π’ΠΎΡ‚ ΠΏΠΎΡ‡Π΅ΠΌΡƒ Π½Π΅ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ΅ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΠ΅ вычислСний ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΎ просто ΠΊΠ°ΠΊ пустой список. Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΎΠ± ошибкС отбрасываСтся. Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠΎΠΈΠ³Ρ€Π°Π΅ΠΌ со списками, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ приводят ΠΊ нСуспСху Π² вычислСниях:

ghci> [] >>= \x –> ["ΠΏΠ»ΠΎΡ…ΠΎΠΉ","Π±Π΅ΡˆΠ΅Π½Ρ‹ΠΉ","ΠΊΡ€ΡƒΡ‚ΠΎΠΉ"]

[]

ghci> [1,2,3] >>= \x –> []

[]

Π’ ΠΏΠ΅Ρ€Π²ΠΎΠΉ строкС пустой список пСрСдаётся Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ список Π½Π΅ содСрТит элСмСнтов, Π½Π΅Ρ‚ элСмСнтов для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π° ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ являСтся пустой список. Π­Ρ‚ΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ значСния Nothing Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ‚ΠΈΠΏ Maybe. Π’ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΉ строкС ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ элСмСнт пСрСдаётся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π½ΠΎ элСмСнт игнорируСтся, ΠΈ функция просто Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ пустой список. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ функция Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ нСуспСхом для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ элСмСнта, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π² Π½Π΅Ρ‘ ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ Ρ‚Π°ΠΊΠΆΠ΅ являСтся нСуспСх.

Как ΠΈ Π² случаС со значСниями Ρ‚ΠΈΠΏΠ° Maybe, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ†Π΅ΠΏΠ»ΡΡ‚ΡŒ нСсколько списков с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ >>=, распространяя Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ:

ghci> [1,2] >>= \n –> ['a','b'] >>= \ch –> return (n,ch)

[(1,'a'),(1,'b'),(2,'a'),(2,'b')]

Числа ΠΈΠ· списка [1,2] ΡΠ²ΡΠ·Ρ‹Π²Π°ΡŽΡ‚ΡΡ с ΠΎΠ±Ρ€Π°Π·Ρ†ΠΎΠΌ n; символы ΠΈΠ· списка ['a','b'] ΡΠ²ΡΠ·Ρ‹Π²Π°ΡŽΡ‚ΡΡ с ΠΎΠ±Ρ€Π°Π·Ρ†ΠΎΠΌ ch. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ выполняСм Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ return (n, ch) (ΠΈΠ»ΠΈ [(n, ch)]), Ρ‡Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Ρ‹ (n, ch) ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Π΅Ρ‘ Π² ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ контСкст ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС это созданиС наимСньшСго Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ³ΠΎ списка, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ прСдставляСт ΠΏΠ°Ρ€Ρƒ (n, ch) Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΈ ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ Π½Π°ΠΈΠΌΠ΅Π½Π΅Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒΡŽ. Π•Π³ΠΎ влияниС Π½Π° контСкст минимально. ΠœΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ: «Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ элСмСнта Π² спискС [1,2] ΠΎΠ±ΠΎΠΉΡ‚ΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ элСмСнт ΠΈΠ· ['a','b'] ΠΈ произвСсти ΠΊΠΎΡ€Ρ‚Π΅ΠΆ, содСрТащий ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ элСмСнту ΠΈΠ· ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ списка».



Π’ΠΎΠΎΠ±Ρ‰Π΅ говоря, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ функция return ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Π΅Π³ΠΎ Π² ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ контСкст, ΠΎΠ½Π° Π½Π΅ ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ ΠΊΠ°ΠΊΠΈΠΌΠΈ-Ρ‚ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ эффСктами (Π²Ρ€ΠΎΠ΄Π΅ привСдСния ΠΊ Π½Π΅ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌΡƒ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΡŽ вычислСний Π² Ρ‚ΠΈΠΏΠ΅ Maybe ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΡŽ Π΅Ρ‰Ρ‘ большСй нСдСтСрминированности для списков), Π½ΠΎ ΠΎΠ½Π° Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π² качСствС своСго Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°.

Когда ваши Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ значСния Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‚, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΈΡ… вычислСниС ΠΊΠ°ΠΊ Π΄Π΅Ρ€Π΅Π²ΠΎ, Π³Π΄Π΅ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π² спискС прСдставляСт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ Π²Π΅Ρ‚ΠΊΡƒ. Π’ΠΎΡ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π΅ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅, пСрСписанноС Π² Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ do:

listOfTuples :: [(Int,Char)]

listOfTuples = do

   n <– [1,2]

   ch <– ['a','b']

   return (n,ch)

Вакая запись Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‡ΡƒΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹ΠΌ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Π·Π΅Ρ† n ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· списка [1,2], Π° ΠΎΠ±Ρ€Π°Π·Π΅Ρ† ch – ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· списка ['a','b']. Как ΠΈ Π² случаС с Ρ‚ΠΈΠΏΠΎΠΌ Maybe, ΠΌΡ‹ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ элСмСнты ΠΈΠ· монадичСского значСния ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ ΠΈΡ… ΠΊΠ°ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ значСния, Π° опСрация >>= бСспокоится ΠΎ контСкстС Π·Π° нас. ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ΠΎΠΌ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС являСтся Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ.

Нотация do ΠΈ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ списков

ИспользованиС списков Π² Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ do ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°Ρ‚ΡŒ Π²Π°ΠΌ ΠΎ Ρ‡Ρ‘ΠΌ-Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΡƒΠΆΠ΅ Π²ΠΈΠ΄Π΅Π»ΠΈ Ρ€Π°Π½Π΅Π΅. НапримСр, посмотритС Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ кусок ΠΊΠΎΠ΄Π°:

ghci> [(n,ch) | n <– [1,2], ch <– ['a','b']]

[(1,'a'),(1,'b'),(2,'a'),(2,'b')]

Π”Π°! Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ списков! Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅ΠΌ Π½ΠΎΡ‚Π°Ρ†ΠΈΡŽ do, ΠΎΠ±Ρ€Π°Π·Π΅Ρ† n ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π» значСния всСх Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΈΠ· списка [1,2]. Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΎΠ±Ρ€Π°Π·Ρ†Ρƒ ch Π±Ρ‹Π» присвоСн Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΈΠ· списка ['a','b'], Π° послСдняя строка ΠΏΠΎΠΌΠ΅Ρ‰Π°Π»Π° ΠΏΠ°Ρ€Ρƒ (n, ch) Π² контСкст ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (одноэлСмСнтный список) для Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° Π΅Π³ΠΎ Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° Π±Π΅Π· привнСсСния ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ нСдСтСрминированности. Π’ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π΅ списка ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ Ρ‚ΠΎ ΠΆΠ΅ самоС, Π½ΠΎ Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΠΈΡΠ°Ρ‚ΡŒ Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ return Π² ΠΊΠΎΠ½Ρ†Π΅ для Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° ΠΏΠ°Ρ€Ρ‹ (n, ch) Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ выводящая Ρ‡Π°ΡΡ‚ΡŒ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° списка сдСлала это Π·Π° нас.

На самом Π΄Π΅Π»Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ списков ΡΠ²Π»ΡΡŽΡ‚ΡΡ просто синтаксичСским сахаром для использования списков ΠΊΠ°ΠΊ ΠΌΠΎΠ½Π°Π΄. Π’ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌ счётС Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ списков ΠΈ списки, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π² Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ do, пСрСводятся Π² использованиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ >>= для осущСствлСния вычислСний, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±Π»Π°Π΄Π°ΡŽΡ‚ Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒΡŽ.

Класс MonadPlus ΠΈ функция guard

Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ списков ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π½Π°ΠΌ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Ρ‚ΡŒ наши Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅. НапримСр, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡ‚Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Ρ‚ΡŒ список чисСл Π² поискС Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅Ρ… ΠΈΠ· Π½ΠΈΡ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ содСрТат Ρ†ΠΈΡ„Ρ€Ρƒ 7:

ghci> [x | x <– [1..50], '7' `elem` show x]

[7,17,27,37,47]

ΠœΡ‹ примСняСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ show ΠΊ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρƒ x Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ нашС число Π² строку, Π° Π·Π°Ρ‚Π΅ΠΌ провСряСм, являСтся Π»ΠΈ символ '7' Ρ‡Π°ΡΡ‚ΡŒΡŽ этой строки.

Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ, ΠΊΠ°ΠΊ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΡ Π² Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°Ρ… списков прСобразуСтся Π² ΡΠΏΠΈΡΠΊΠΎΠ²ΡƒΡŽ ΠΌΠΎΠ½Π°Π΄Ρƒ, ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ guard ΠΈ класс Ρ‚ΠΈΠΏΠΎΠ² MonadPlus.

Класс Ρ‚ΠΈΠΏΠΎΠ² MonadPlus ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для ΠΌΠΎΠ½Π°Π΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠ³ΡƒΡ‚ вСсти сСбя ΠΊΠ°ΠΊ ΠΌΠΎΠ½ΠΎΠΈΠ΄Ρ‹. Π’ΠΎΡ‚ Π΅Π³ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅:

class Monad m => MonadPlus m where

   mzero :: m a

   mplus :: m a –> m a –> m a

Ѐункция mzero являСтся синонимом Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ mempty ΠΈΠ· класса Ρ‚ΠΈΠΏΠΎΠ² Monoid, Π° функция mplus соотвСтствуСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ mappend. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ списки ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΌΠΎΠ½ΠΎΠΈΠ΄Π°ΠΌΠΈ, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠ½Π°Π΄Π°ΠΌΠΈ, ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ экзСмпляром этого класса Ρ‚ΠΈΠΏΠΎΠ²:

instance MonadPlus [] where

   mzero = []

   mplus = (++)

Для списков функция mzero прСдставляСт Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ вычислСниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° – Π½Π΅ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΎΠΊΠΎΠ½Ρ‡ΠΈΠ²ΡˆΠ΅Π΅ΡΡ вычислСниС. Ѐункция mplus сводит Π΄Π²Π° Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… значСния Π² ΠΎΠ΄Π½ΠΎ. Ѐункция guard ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

guard :: (MonadPlus m) => Bool –> m ()

guard True = return ()

guard False = mzero

Ѐункция guard ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Bool. Если это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π²Π½ΠΎ True, функция guard Π±Π΅Ρ€Ρ‘Ρ‚ пустой ΠΊΠΎΡ€Ρ‚Π΅ΠΆ () ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π΅Π³ΠΎ Π² ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ контСкст, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ являСтся ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹ΠΌ. Если Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Bool Ρ€Π°Π²Π½ΠΎ False, функция guard создаёт монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ с Π½Π΅ΡƒΠ΄Π°Ρ‡Π΅ΠΉ Π² вычислСниях. Π’ΠΎΡ‚ эта функция Π² дСйствии:

ghci> guard (5 > 2) :: Maybe ()

Just ()

ghci> guard (1 > 2) :: Maybe ()

Nothing

ghci> guard (5 > 2) :: [()]

[()]

ghci> guard (1 > 2) :: [()]

[]

Выглядит интСрСсно, Π½ΠΎ Ρ‡Π΅ΠΌ это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ? Π’ списковой ΠΌΠΎΠ½Π°Π΄Π΅ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π΅Ρ‘ для Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΠΈ Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… вычислСний:

ghci> [1..50] >>= (\x –> guard ('7' `elem` show x) >> return x)

[7,17,27,37,47]

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π΅Π½ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ Π±Ρ‹Π» Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Ρ‘Π½ нашим ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΌ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ списка. Как функция guard достигла этого? Π”Π°Π²Π°ΠΉΡ‚Π΅ сначала посмотрим, ΠΊΠ°ΠΊ ΠΎΠ½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€ΡƒΠ΅Ρ‚ совмСстно с ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠ΅ΠΉ >>:

ghci> guard (5 > 2) >> return "ΠΊΠ»Ρ‘Π²ΠΎ" :: [String]

["ΠΊΠ»Ρ‘Π²ΠΎ"]

ghci> guard (1 > 2) >> return "ΠΊΠ»Ρ‘Π²ΠΎ" :: [String]

[]

Если функция guard срабатываСт ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ, находящимся Π² Π½Π΅ΠΉ, Π±ΡƒΠ΄Π΅Ρ‚ пустой ΠΊΠΎΡ€Ρ‚Π΅ΠΆ. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ дальшС ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ >>, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ этот пустой ΠΊΠΎΡ€Ρ‚Π΅ΠΆ ΠΈ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Ρ‡Ρ‚ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°. Однако Ссли функция guard Π½Π΅ срабатываСт ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, функция return впослСдствии Ρ‚ΠΎΠΆΠ΅ Π½Π΅ сработаСт ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° пустого списка Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ >>= всСгда Π΄Π°Ρ‘Ρ‚ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ пустой список. Ѐункция guard просто Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚: «Если это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Bool Ρ€Π°Π²Π½ΠΎ False, Π²Π΅Ρ€Π½ΠΈ Π½Π΅ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ΅ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΠ΅ вычислСний прямо здСсь. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС создай ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ содСрТит Π² сСбС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅-ΠΏΡƒΡΡ‚Ρ‹ΡˆΠΊΡƒ ()Β». Всё, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° Π΄Π΅Π»Π°Π΅Ρ‚, – позволяСт Π²Ρ‹Ρ‡ΠΈΡΠ»Π΅Π½ΠΈΡŽ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒΡΡ.

Π’ΠΎΡ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, пСрСписанный Π² Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ do:

sevensOnly :: [Int]

sevensOnly = do

   x <– [1..50]

   guard ('7' `elem` show x)

   return x

Если Π±Ρ‹ ΠΌΡ‹ Π·Π°Π±Ρ‹Π»ΠΈ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π·Π΅Ρ† x Π² качСствС ΠΎΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ return, Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ список состоял Π±Ρ‹ просто ΠΈΠ· пустых ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ΅ΠΉ. Π’ΠΎΡ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π² Ρ„ΠΎΡ€ΠΌΠ΅ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° списка: