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

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

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

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

[7,17,27,37,47]

ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΡ Π² Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°Ρ… списков – это Ρ‚ΠΎ ΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ использованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ guard.

Π₯ΠΎΠ΄ ΠΊΠΎΠ½Ρ‘ΠΌ

Π•ΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, которая ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ нСдСтСрминированности. Π‘ΠΊΠ°ΠΆΠ΅ΠΌ, Ρƒ нас Π΅ΡΡ‚ΡŒ ΡˆΠ°Ρ…ΠΌΠ°Ρ‚Π½Π°Ρ доска ΠΈ Π½Π° Π½Π΅ΠΉ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Π° Ρ„ΠΈΠ³ΡƒΡ€Π° – конь. ΠœΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, ΠΌΠΎΠΆΠ΅Ρ‚ Π»ΠΈ конь Π΄ΠΎΡΡ‚ΠΈΠ³Π½ΡƒΡ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΠΎΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ Π² Ρ‚Ρ€ΠΈ Ρ…ΠΎΠ΄Π°. Π‘ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Ρƒ чисСл для прСдставлСния ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ коня Π½Π° ΡˆΠ°Ρ…ΠΌΠ°Ρ‚Π½ΠΎΠΉ доскС. ΠŸΠ΅Ρ€Π²ΠΎΠ΅ число Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ столбСц, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΠ½ находится, Π° Π²Ρ‚ΠΎΡ€ΠΎΠ΅ число – строку.



Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ синоним Ρ‚ΠΈΠΏΠ° для Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ коня Π½Π° ΡˆΠ°Ρ…ΠΌΠ°Ρ‚Π½ΠΎΠΉ доскС.

type KnightPos = (Int, Int)

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ конь Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ с ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ (6, 2). ΠœΠΎΠΆΠ΅Ρ‚ Π»ΠΈ ΠΎΠ½ Π΄ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ Π΄ΠΎ (6, 1) ΠΈΠΌΠ΅Π½Π½ΠΎ Π·Π° Ρ‚Ρ€ΠΈ Ρ…ΠΎΠ΄Π°? Какой Ρ…ΠΎΠ΄ Π»ΡƒΡ‡ΡˆΠ΅ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΈΠ· Π΅Π³ΠΎ Π½Ρ‹Π½Π΅ΡˆΠ½Π΅ΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ? Π― знаю: ΠΊΠ°ΠΊ насчёт ΠΈΡ… всСх?! К нашим услугам Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ, поэтому вмСсто Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ Ρ…ΠΎΠ΄, Π΄Π°Π²Π°ΠΉΡ‚Π΅ просто Π²Ρ‹Π±Π΅Ρ€Π΅ΠΌ ΠΈΡ… всС сразу! Π’ΠΎΡ‚ функция, которая Π±Π΅Ρ€Ρ‘Ρ‚ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ коня ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ всС Π΅Π³ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Ρ…ΠΎΠ΄Ρ‹:

moveKnight :: KnightPos –> [KnightPos]

moveKnight (c,r) = do

   (c',r') <– [(c+2,r-1),(c+2,r+1),(c-2,r-1),(c-2,r+1)

              ,(c+1,r-2),(c+1,r+2),(c-1,r-2),(c-1,r+2)

              ]

   guard (c' `elem` [1..8] && r' `elem` [1..8])

   return (c',r')

Конь всСгда ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒΡΡ Π½Π° ΠΎΠ΄Π½Ρƒ ΠΊΠ»Π΅Ρ‚ΠΊΡƒ Π³ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½ΠΎ ΠΈΠ»ΠΈ Π²Π΅Ρ€Ρ‚ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎ ΠΈ Π½Π° Π΄Π²Π΅ ΠΊΠ»Π΅Ρ‚ΠΊΠΈ Π²Π΅Ρ€Ρ‚ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎ ΠΈΠ»ΠΈ Π³ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½ΠΎ, ΠΏΡ€ΠΈΡ‡Ρ‘ΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π΅Π³ΠΎ Ρ…ΠΎΠ΄ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ ΠΈ ΠΏΠΎ Π³ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΠΈ, ΠΈ ΠΏΠΎ Π²Π΅Ρ€Ρ‚ΠΈΠΊΠ°Π»ΠΈ. ΠŸΠ°Ρ€Π° (c', r') ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· списка ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΉ, Π° Π·Π°Ρ‚Π΅ΠΌ функция guard заботится ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½ΠΎΠ²Ρ‹ΠΉ Ρ…ΠΎΠ΄, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΏΠ°Ρ€Π° (c', r'), Π±Ρ‹Π» Π² ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… доски. Если Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΡ‚ Π·Π° доску, ΠΎΠ½Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ пустой список, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π½Π΅ΡƒΠ΄Π°Ρ‡Π΅, ΠΈ Π²Ρ‹Π·ΠΎΠ² return (c', r') Π½Π΅ обрабатываСтся для Π΄Π°Π½Π½ΠΎΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ.

Π­Ρ‚Π° функция ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ записана ΠΈ Π±Π΅Π· использования списков Π² качСствС ΠΌΠΎΠ½Π°Π΄. Π’ΠΎΡ‚ ΠΊΠ°ΠΊ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π΅Ρ‘ с использованиСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ filter:

moveKnight :: KnightPos –> [KnightPos]

moveKnight (c,r) = filter onBoard

   [(c+2,r-1),(c+2,r+1),(c-2,r-1),(c-2,r+1)

   ,(c+1,r-2),(c+1,r+2),(c-1,r-2),(c-1,r+2)

   ]

   where onBoard (c,r) = c `elem` [1..8] && r `elem` [1..8]

ОбС вСрсии Π΄Π΅Π»Π°ΡŽΡ‚ ΠΎΠ΄Π½ΠΎ ΠΈ Ρ‚ΠΎ ΠΆΠ΅, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π²Ρ‹Π±ΠΈΡ€Π°ΠΉΡ‚Π΅ Ρ‚Ρƒ, которая каТСтся Π²Π°ΠΌ Π»ΡƒΡ‡ΡˆΠ΅. Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ:

ghci> moveKnight (6, 2)

[(8,1),(8,3),(4,1),(4,3),(7,4),(5,4)]

ghci> moveKnight (8, 1)

[(6,2),(7,3)]

Π Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ чудСсно! ΠœΡ‹ Π±Π΅Ρ€Ρ‘ΠΌ ΠΎΠ΄Π½Ρƒ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈ просто выполняСм всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ Ρ…ΠΎΠ΄Ρ‹ сразу, Ρ‚Π°ΠΊ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ.

ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° Ρƒ нас Π΅ΡΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ нСдСтСрминированная позиция, ΠΌΡ‹ просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ >>=, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π΅Ρ‘ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ moveKnight. Π’ΠΎΡ‚ функция, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π°Ρ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰Π°Ρ всС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄ΠΎΡΡ‚ΠΈΠ³Π½ΡƒΡ‚ΡŒ ΠΈΠ· Π½Π΅Ρ‘ Π² Ρ‚Ρ€ΠΈ Ρ…ΠΎΠ΄Π°:

in3 :: KnightPos –> [KnightPos]

in3 start = do

   first <– moveKnight start

   second <– moveKnight first

   moveKnight second

Если Π²Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΄ΠΈΡ‚Π΅ Π΅ΠΉ ΠΏΠ°Ρ€Ρƒ (6, 2), Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ список Π±ΡƒΠ΄Π΅Ρ‚ довольно большим. ΠŸΡ€ΠΈΡ‡ΠΈΠ½Π° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ссли Π΅ΡΡ‚ΡŒ нСсколько ΠΏΡƒΡ‚Π΅ΠΉ Π΄ΠΎΡΡ‚ΠΈΠ³Π½ΡƒΡ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΠΎΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ Π² Ρ‚Ρ€ΠΈ Ρ…ΠΎΠ΄Π°, Ρ…ΠΎΠ΄ Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½ΠΎ появляСтся Π² спискС нСсколько Ρ€Π°Π·.

Π’ΠΎΡ‚ ΠΏΡ€Π΅Π΄ΡˆΠ΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ Π±Π΅Π· использования Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ do:

in3 start = return start >>= moveKnight >>= moveKnight >>= moveKnight

ΠžΠ΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎΠ΅ использованиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ >>= Π΄Π°Ρ‘Ρ‚ Π½Π°ΠΌ всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ Ρ…ΠΎΠ΄Ρ‹ с Π½Π°Ρ‡Π°Π»Π°. Когда ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ >>= Π²Ρ‚ΠΎΡ€ΠΎΠΉ Ρ€Π°Π·, Ρ‚ΠΎ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ³ΠΎ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Ρ…ΠΎΠ΄Π° вычисляСтся ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ΠΉ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ…ΠΎΠ΄; Ρ‚ΠΎ ΠΆΠ΅ самоС Π²Π΅Ρ€Π½ΠΎ ΠΈ Π² ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠΈ послСднСго Ρ…ΠΎΠ΄Π°.

ΠŸΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ значСния Π² контСкст ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ с ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ ΠΊ Π½Π΅ΠΌΡƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ return, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ с использованиСм ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ >>= – Ρ‚ΠΎ ΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΊ Π΄Π°Π½Π½ΠΎΠΌΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ; Π½ΠΎ ΠΌΡ‹ сдСлали это здСсь, Π²ΠΎ всяком случаС, Ρ€Π°Π΄ΠΈ стиля.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π°Π²Π°ΠΉΡ‚Π΅ создадим Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π΄Π²Π΅ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈ сообщаСт Π½Π°ΠΌ, ΠΌΠΎΠΆΠ΅ΠΌ Π»ΠΈ ΠΌΡ‹ ΠΏΠΎΠΏΠ°ΡΡ‚ΡŒ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠΉ Π² Π΄Ρ€ΡƒΠ³ΡƒΡŽ Ρ€ΠΎΠ²Π½ΠΎ Π² Ρ‚Ρ€ΠΈ Ρ…ΠΎΠ΄Π°:

canReachIn3 :: KnightPos –> KnightPos –> Bool

canReachIn3 start end = end `elem` in3 start

ΠœΡ‹ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌ всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ Π² ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… Ρ‚Ρ€Ρ‘Ρ… Ρ…ΠΎΠ΄ΠΎΠ², Π° Π·Π°Ρ‚Π΅ΠΌ провСряСм, находится Π»ΠΈ срСди Π½ΠΈΡ… искомая.

Π’ΠΎΡ‚ ΠΊΠ°ΠΊ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, ΠΌΠΎΠΆΠ΅ΠΌ Π»ΠΈ ΠΌΡ‹ ΠΏΠΎΠΏΠ°ΡΡ‚ΡŒ ΠΈΠ· (6,2) Π² (6,1) Π² Ρ‚Ρ€ΠΈ Ρ…ΠΎΠ΄Π°:

ghci> (6, 2) `canReachIn3` (6, 1)

True

Π”Π°! Как насчёт ΠΈΠ· (6, 2) Π² (7, 3)?

ghci> (6, 2) `canReachIn3` (7, 3)

False

НСт! Π’ качСствС упраТнСния Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½Π° ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π»Π° Π²Π°ΠΌ Ρ…ΠΎΠ΄Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄ΠΎΡΡ‚ΠΈΠ³Π½ΡƒΡ‚ΡŒ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠΉ. Π’ Π³Π»Π°Π²Π΅ 14 Π²Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅, ΠΊΠ°ΠΊ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π΅ΠΉ число Ρ…ΠΎΠ΄ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ произвСсти, вмСсто Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ это число Тёстко, ΠΊΠ°ΠΊ сСйчас.

Π—Π°ΠΊΠΎΠ½Ρ‹ ΠΌΠΎΠ½Π°Π΄

Π’Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ Π² ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€ΠΎΠ² ΠΈ Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€ΠΎΠ², Π² ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠΈ ΠΌΠΎΠ½Π°Π΄ дСйствуСт нСсколько Π·Π°ΠΊΠΎΠ½ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΠΎΠ΄Ρ‡ΠΈΠ½ΡΡ‚ΡŒΡΡ всС экзСмпляры класса Monad. Π”Π°ΠΆΠ΅ Ссли Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ сдСлано экзСмпляром класса Ρ‚ΠΈΠΏΠΎΠ² Monad, это Π΅Ρ‰Ρ‘ Π½Π΅ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π½Π° самом Π΄Π΅Π»Π΅ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°ΠΌΠΈ ΠΌΠΎΠ½Π°Π΄Π°. Π§Ρ‚ΠΎΠ±Ρ‹ Ρ‚ΠΈΠΏ ΠΏΠΎ-настоящСму Π±Ρ‹Π» ΠΌΠΎΠ½Π°Π΄ΠΎΠΉ, для Π½Π΅Π³ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π·Π°ΠΊΠΎΠ½Ρ‹ ΠΌΠΎΠ½Π°Π΄. Π­Ρ‚ΠΈ Π·Π°ΠΊΠΎΠ½Ρ‹ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π½Π°ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ обоснованныС прСдполоТСния ΠΎ Ρ‚ΠΈΠΏΠ΅ ΠΈ Π΅Π³ΠΎ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠΈ.



Π―Π·Ρ‹ΠΊ Haskell позволяСт Π»ΡŽΠ±ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ Π±Ρ‹Ρ‚ΡŒ экзСмпляром любого класса Ρ‚ΠΈΠΏΠΎΠ², ΠΏΠΎΠΊΠ° Ρ‚ΠΈΠΏΡ‹ удаётся ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ. Π’ΠΏΡ€ΠΎΡ‡Π΅ΠΌ, ΠΎΠ½ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π»ΠΈ Π·Π°ΠΊΠΎΠ½Ρ‹ ΠΌΠΎΠ½Π°Π΄ для Ρ‚ΠΈΠΏΠ°, поэтому Ссли ΠΌΡ‹ создаём Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр класса Ρ‚ΠΈΠΏΠΎΠ² Monad, ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠ±Π»Π°Π΄Π°Ρ‚ΡŒ достаточной ΡƒΠ²Π΅Ρ€Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ с Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ Π·Π°ΠΊΠΎΠ½ΠΎΠ² ΠΌΠΎΠ½Π°Π΄ для этого Ρ‚ΠΈΠΏΠ° всё Ρ…ΠΎΡ€ΠΎΡˆΠΎ. МоТно ΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏΡ‹ Π² стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‚ Π·Π°ΠΊΠΎΠ½Π°ΠΌ, Π½ΠΎ ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Ρ‘ΠΌ ΠΊ созданию собствСнных ΠΌΠΎΠ½Π°Π΄, Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°ΠΊΠΎΠ½ΠΎΠ² Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ. Π’ΠΏΡ€ΠΎΡ‡Π΅ΠΌ, Π½Π΅ Π±Π΅ΡΠΏΠΎΠΊΠΎΠΉΡ‚Π΅ΡΡŒ – эти Π·Π°ΠΊΠΎΠ½Ρ‹ совсСм Π½Π΅ слоТны!

ЛСвая Π΅Π΄ΠΈΠ½ΠΈΡ†Π°

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Π·Π°ΠΊΠΎΠ½ ΠΌΠΎΠ½Π°Π΄ ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Ссли ΠΌΡ‹ Π±Π΅Ρ€Ρ‘ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π΅Π³ΠΎ Π² контСкст ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ return, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‘ΠΌ Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ >>=, это Ρ€Π°Π²Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ Ρ‚ΠΎΠΌΡƒ, ΠΊΠ°ΠΊ Ссли Π±Ρ‹ ΠΌΡ‹ просто взяли Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠ»ΠΈ ΠΊ Π½Π΅ΠΌΡƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. Говоря Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ, return x >>= f – это Ρ‚ΠΎ ΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ f x.

Если Π²Ρ‹ посмотритС Π½Π° монадичСскиС значСния ΠΊΠ°ΠΊ Π½Π° значСния с контСкстом ΠΈ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ return ΠΊΠ°ΠΊ Π½Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ значСния ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Π΅Π³ΠΎ Π² ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ контСкст ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Ρ‚ΠΎ Π·Π°ΠΊΠΎΠ½ ΠΈΠΌΠ΅Π΅Ρ‚ смысл. Если Π΄Π°Π½Π½Ρ‹ΠΉ контСкст Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π΅Π½, ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° этого монадичСского значСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Π° сильно ΠΎΡ‚Π»ΠΈΡ‡Π°Ρ‚ΡŒΡΡ ΠΎΡ‚ простого примСнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ – ΠΈ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½ΠΈΡ‡Π΅ΠΌ Π½Π΅ отличаСтся.

Ѐункция return для ΠΌΠΎΠ½Π°Π΄Ρ‹ Maybe ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° ΠΊΠ°ΠΊ Π²Ρ‹Π·ΠΎΠ² конструктора Just. Вся ΡΡƒΡ‚ΡŒ ΠΌΠΎΠ½Π°Π΄Ρ‹ Maybe состоит Π² Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΌ нСуспСхС Π² вычислСниях, ΠΈ Ссли Ρƒ нас Π΅ΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π² Ρ‚Π°ΠΊΠΎΠΉ контСкст, Π΅ΡΡ‚ΡŒ смысл Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΊΠ°ΠΊ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ΅ вычислСниС, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ, ΠΊΠ°ΠΊΠΈΠΌ являСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π’ΠΎΡ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ return с Ρ‚ΠΈΠΏΠΎΠΌ Maybe:

ghci> return 3 >>= (\x –> Just (x+100000))

Just 100003

ghci> (\x –> Just (x+100000)) 3

Just 100003

Для списковой ΠΌΠΎΠ½Π°Π΄Ρ‹ функция return ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Ρ‡Ρ‚ΠΎ-Π»ΠΈΠ±ΠΎ Π² одноэлСмСнтный список. РСализация ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ >>= для списков ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ ΠΏΠΎ всСм значСниям Π² спискС ΠΈ примСняСт ΠΊ Π½ΠΈΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. Однако, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π² одноэлСмСнтном спискС лишь ΠΎΠ΄Π½ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, это Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΊ Π΄Π°Π½Π½ΠΎΠΌΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ:

ghci> return "WoM" >>= (\x –> [x,x,x])

["WoM","WoM","WoM"]

ghci> (\x –> [x,x,x]) "WoM"

["WoM","WoM","WoM"]

Π’Ρ‹ Π·Π½Π°Π΅Ρ‚Π΅, Ρ‡Ρ‚ΠΎ для ΠΌΠΎΠ½Π°Π΄Ρ‹ IO использованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ return создаёт дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Ρ… эффСктов, Π½ΠΎ просто Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² качСствС своСго Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°. По этому Π²ΠΏΠΎΠ»Π½Π΅ Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ, Ρ‡Ρ‚ΠΎ этот Π·Π°ΠΊΠΎΠ½ выполняСтся Ρ‚Π°ΠΊΠΆΠ΅ ΠΈ для ΠΌΠΎΠ½Π°Π΄Ρ‹ IO.

ΠŸΡ€Π°Π²Π°Ρ Π΅Π΄ΠΈΠ½ΠΈΡ†Π°

Π’Ρ‚ΠΎΡ€ΠΎΠΉ Π·Π°ΠΊΠΎΠ½ ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Ссли Ρƒ нас Π΅ΡΡ‚ΡŒ монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ >>= для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ return, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ Π±ΡƒΠ΄Π΅Ρ‚ нашС ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π€ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ m >>= return являСтся Π½Π΅ Ρ‡Π΅ΠΌ ΠΈΠ½Ρ‹ΠΌ, ΠΊΠ°ΠΊ просто m.

Π­Ρ‚ΠΎΡ‚ Π·Π°ΠΊΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‡ΡƒΡ‚ΡŒ ΠΌΠ΅Π½Π΅Π΅ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π΅Π½, Ρ‡Π΅ΠΌ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ. Π”Π°Π²Π°ΠΉΡ‚Π΅ посмотрим, ΠΏΠΎΡ‡Π΅ΠΌΡƒ ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ. Когда ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‘ΠΌ монадичСскиС значСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ >>=, эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ значСния ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ монадичСскиС. Ѐункция return Ρ‚ΠΎΠΆΠ΅ являСтся Ρ‚Π°ΠΊΠΎΠΉ, Ссли Π²Ρ‹ рассмотритС Π΅Ρ‘ Ρ‚ΠΈΠΏ.