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

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

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

((),[10,1,2,0,0,0])

Π—Π΄Π΅ΡΡŒ анонимная функция ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ состояниС, ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ 2 ΠΈ 1 Π² стСк ΠΈ прСдставляСт push 10 ΠΊΠ°ΠΊ свой Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΊΠΎΠ³Π΄Π° всё это разглаТиваСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ join, Π° Π·Π°Ρ‚Π΅ΠΌ выполняСтся, всё это Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ сначала ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ значСния 2 ΠΈ 1 Π² стСк, Π° Π·Π°Ρ‚Π΅ΠΌ выполняСтся Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ push 10, проталкивая число 10 Π½Π° Π²Π΅Ρ€Ρ…ΡƒΡˆΠΊΡƒ.

РСализация для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ join Ρ‚Π°ΠΊΠΎΠ²Π°:

join :: (Monad m) => m (m a) –> m a

join mm = do

   m <– mm

   m

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ mm являСтся монадичСским Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ, ΠΌΡ‹ Π±Π΅Ρ€Ρ‘ΠΌ этот Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π° Π·Π°Ρ‚Π΅ΠΌ просто ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π΅Π³ΠΎ Π½Π° Π΅Π³ΠΎ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ строку, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ это ΠΈ Π΅ΡΡ‚ΡŒ монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π’Ρ€ΡŽΠΊ здСсь Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ m <– mm, контСкст ΠΌΠΎΠ½Π°Π΄Ρ‹, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΡ‹ находимся, Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½. Π’ΠΎΡ‚ ΠΏΠΎΡ‡Π΅ΠΌΡƒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, значСния Ρ‚ΠΈΠΏΠ° Maybe Π΄Π°ΡŽΡ‚ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ значСния Just, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли ΠΈ внСшнСС, ΠΈ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π΅ значСния ΡΠ²Π»ΡΡŽΡ‚ΡΡ значСниями Just. Π’ΠΎΡ‚ ΠΊΠ°ΠΊ это выглядСло Π±Ρ‹, Ссли Π±Ρ‹ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ mm Π±Ρ‹Π»ΠΎ Π·Π°Ρ€Π°Π½Π΅Π΅ установлСно Π² Just (Just 8):

joinedMaybes :: Maybe Int

joinedMaybes = do

   m <– Just (Just 8)

   m

НавСрноС, самоС интСрСсноС Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ join – Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ для любой ΠΌΠΎΠ½Π°Π΄Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° монадичСского значСния Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ >>= прСдставляСт собой Ρ‚ΠΎ ΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ просто ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ значСния с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π° Π·Π°Ρ‚Π΅ΠΌ использованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ join для разглаТивания Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ монадичСского значСния! Π”Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ m >>= f – всСгда Ρ‚ΠΎ ΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ join (fmap f m). Если Π²Π΄ΡƒΠΌΠ°Ρ‚ΡŒΡΡ, это ΠΈΠΌΠ΅Π΅Ρ‚ смысл.

ΠŸΡ€ΠΈ использовании ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ >>= ΠΌΡ‹ постоянно Π΄ΡƒΠΌΠ°Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ монадичСскоС. Если ΠΌΡ‹ просто ΠΎΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΠΌ монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²Π½ΡƒΡ‚Ρ€ΠΈ монадичСского значСния. НапримСр, скаТСм, Ρƒ нас Π΅ΡΡ‚ΡŒ Just 9 ΠΈ функция \x –> Just (x+1). Если с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΌΡ‹ ΠΎΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΠΌ Just 9, Ρƒ нас останСтся Just (Just 10).

Π’ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ m >>= f всСгда Ρ€Π°Π²Π½ΠΎ join (fmap f m), ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, Ссли ΠΌΡ‹ создаём свой собствСнный экзСмпляр класса Monad для Π½Π΅ΠΊΠΎΠ΅Π³ΠΎ Ρ‚ΠΈΠΏΠ°. Π­Ρ‚ΠΎ связано с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ ΠΏΡ€ΠΎΡ‰Π΅ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ ΠΌΡ‹ Π±Ρ‹ Ρ€Π°Π·Π³Π»Π°Π΄ΠΈΠ»ΠΈ Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ρ‡Π΅ΠΌ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ >>=.



Π•Ρ‰Ρ‘ интСрСсно Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ функция join Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π°, всСго лишь ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, прСдоставляСмыС Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Π°ΠΌΠΈ ΠΈ Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Π°ΠΌΠΈ. Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ нас ΠΊ Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡŽ, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠ½Π°Π΄Ρ‹ Π½Π΅ просто сопоставимы ΠΏΠΎ своСй силС с Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Π°ΠΌΠΈ ΠΈ Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Π°ΠΌΠΈ – ΠΎΠ½ΠΈ Π½Π° самом Π΄Π΅Π»Π΅ сильнСС, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ с Π½ΠΈΠΌΠΈ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ большС, Ρ‡Π΅ΠΌ просто с Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Π°ΠΌΠΈ ΠΈ Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Π°ΠΌΠΈ.

Ѐункция filterM

Ѐункция filter – это просто Ρ…Π»Π΅Π± программирования Π½Π° языкС Haskell (ΠΏΡ€ΠΈ Ρ‚ΠΎΠΌ Ρ‡Ρ‚ΠΎ функция map – масло). Она ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ ΠΈ список, ΠΏΠΎΠ΄Π»Π΅ΠΆΠ°Ρ‰ΠΈΠΉ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΠΈ, Π° Π·Π°Ρ‚Π΅ΠΌ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ список, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ элСмСнты, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‚ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚Ρƒ. Π•Ρ‘ Ρ‚ΠΈΠΏ Ρ‚Π°ΠΊΠΎΠ²:

filter :: (a –> Bool) –> [a] –> [a]

ΠŸΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ Π±Π΅Ρ€Ρ‘Ρ‚ элСмСнт списка ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Bool. А Π²Π΄Ρ€ΡƒΠ³ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Ρ‘Π½Π½ΠΎΠ΅ ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Bool Π±Ρ‹Π»ΠΎ Π½Π° самом Π΄Π΅Π»Π΅ монадичСским? Π§Ρ‚ΠΎ Ссли ΠΊ Π½Π΅ΠΌΡƒ Π±Ρ‹Π» ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ контСкст?.. НапримСр, ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ True ΠΈΠ»ΠΈ False, ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Ρ‘Π½Π½ΠΎΠ΅ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ΠΎΠΌ, ΠΈΠΌΠ΅Π»ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ ΡΠΎΠΏΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ ΠΌΠΎΠ½ΠΎΠΈΠ΄Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²Ρ€ΠΎΠ΄Π΅ ["ΠŸΡ€ΠΈΠ½ΡΡ‚ΠΎ число 5"] ΠΈΠ»ΠΈ ["3 слишком ΠΌΠ°Π»ΠΎ"]? Если Π±Ρ‹ это Π±Ρ‹Π»ΠΎ Ρ‚Π°ΠΊ, ΠΌΡ‹ Π±Ρ‹ ΠΎΠΆΠΈΠ΄Π°Π»ΠΈ, Ρ‡Ρ‚ΠΎ ΠΊ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌΡƒ списку Ρ‚ΠΎΠΆΠ΅ прилагаСтся ΠΆΡƒΡ€Π½Π°Π» всСх ΠΆΡƒΡ€Π½Π°Π»ΡŒΠ½Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±Ρ‹Π»ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½Ρ‹ Π½Π° ΠΏΡƒΡ‚ΠΈ. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ссли Π±Ρ‹ ΠΊ списку, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Ρ‘Π½Π½ΠΎΠΌΡƒ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ΠΎΠΌ, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Bool, Π±Ρ‹Π» ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ контСкст, ΠΌΡ‹ ΠΎΠΆΠΈΠ΄Π°Π»ΠΈ Π±Ρ‹, Ρ‡Ρ‚ΠΎ ΠΊ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌΡƒ списку Ρ‚ΠΎΠΆΠ΅ ΠΏΡ€ΠΈΠΊΡ€Π΅ΠΏΠ»Ρ‘Π½ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ контСкст. Π˜Π½Π°Ρ‡Π΅ контСкст, ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ Ρ‚ΠΈΠΏΠ° Bool, Π±Ρ‹Π» Π±Ρ‹ ΡƒΡ‚Ρ€Π°Ρ‡Π΅Π½.

Ѐункция filterM ΠΈΠ· модуля Control.Monad Π΄Π΅Π»Π°Π΅Ρ‚ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ! Π•Ρ‘ Ρ‚ΠΈΠΏ Ρ‚Π°ΠΊΠΎΠ²:

filterM :: (Monad m) => (a –> m Bool) –> [a] –> m [a]

ΠŸΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ – Ρ‚ΠΈΠΏΠ° Bool, Π½ΠΎ ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ это монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π΅Π³ΠΎ контСкст ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ всСм Ρ‡Π΅ΠΌ ΡƒΠ³ΠΎΠ΄Π½ΠΎ, ΠΎΡ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ Π½Π΅ΡƒΠ΄Π°Ρ‡ΠΈ Π΄ΠΎ нСдСтСрминированности ΠΈ Π±ΠΎΠ»Π΅Π΅! Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ ΠΎΡ‚Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ контСкста Π² ΠΎΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ‚ΠΎΠΆΠ΅ являСтся монадичСским Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ.

Π”Π°Π²Π°ΠΉΡ‚Π΅ Π²ΠΎΠ·ΡŒΠΌΡ‘ΠΌ список ΠΈ оставим Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ значСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ мСньшС 4. Для Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΎΠ±Ρ‹Ρ‡Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ filter:

ghci> filter (\x –> x < 4) [9,1,5,2,10,3]

[1,2,3]

Π­Ρ‚ΠΎ довольно просто. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π°Π²Π°ΠΉΡ‚Π΅ создадим ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠΌΠΈΠΌΠΎ прСдставлСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° True ΠΈΠ»ΠΈ False Ρ‚Π°ΠΊΠΆΠ΅ прСдоставляСт ΠΆΡƒΡ€Π½Π°Π» своих дСйствий. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ ΠΆΠ΅, для этого ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ½Π°Π΄Ρƒ Writer:

keepSmall :: Int –> Writer [String] Bool

keepSmall x

   | x < 4 = do

        tell ["БохраняСм " ++ show x]

        return True

   | otherwise = do

        tell [show x ++ " слишком Π²Π΅Π»ΠΈΠΊΠΎ, выбрасываСм"]

        return False

ВмСсто Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ просто Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Bool, функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Writer [String] Bool. Π­Ρ‚ΠΎ монадичСский ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚. Π—Π²ΡƒΡ‡ΠΈΡ‚ Π½Π΅ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ, Π½Π΅ Ρ‚Π°ΠΊ Π»ΠΈ? Если число мСньшС числа 4, ΠΌΡ‹ сообщаСм, Ρ‡Ρ‚ΠΎ оставили Π΅Π³ΠΎ, Π° Π·Π°Ρ‚Π΅ΠΌ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ True.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΄ΠΈΠΌ Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ filterM вмСстС со списком. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Writer, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ список Ρ‚Π°ΠΊΠΆΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Ρ‚ΠΈΠΏΠ° Writer.

ghci> fst $ runWriter $ filterM keepSmall [9,1,5,2,10,3]

[1,2,3]

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΡ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ значСния ΠΌΠΎΠ½Π°Π΄Ρ‹ Writer, ΠΌΡ‹ Π²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ всё Π² порядкС. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π°Π²Π°ΠΉΡ‚Π΅ распСчатаСм ΠΆΡƒΡ€Π½Π°Π» ΠΈ посмотрим, Ρ‡Ρ‚ΠΎ Ρƒ нас Π΅ΡΡ‚ΡŒ:

ghci> mapM_ putStrLn $ snd $ runWriter $ filterM keepSmall [9,1,5,2,10,3]

9 слишком Π²Π΅Π»ΠΈΠΊΠΎ, выбрасываСм

БохраняСм 1

5 слишком Π²Π΅Π»ΠΈΠΊΠΎ, выбрасываСм

БохраняСм 2

10 слишком Π²Π΅Π»ΠΈΠΊΠΎ, выбрасываСм

БохраняСм 3

Π˜Ρ‚Π°ΠΊ, просто прСдоставляя монадичСский ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ filterM, ΠΌΡ‹ смогли Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Ρ‚ΡŒ список, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ возмоТности примСняСмого Π½Π°ΠΌΠΈ монадичСского контСкста.

ΠžΡ‡Π΅Π½ΡŒ ΠΊΡ€ΡƒΡ‚ΠΎΠΉ Ρ‚Ρ€ΡŽΠΊ Π² языкС Haskell – использованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ filterM для получСния мноТСства-стСпСни списка (Ссли ΠΌΡ‹ сСйчас Π±ΡƒΠ΄Π΅ΠΌ Π΄ΡƒΠΌΠ°Ρ‚ΡŒ ΠΎ Π½Ρ‘ΠΌ ΠΊΠ°ΠΊ ΠΎ мноТСствС). ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²ΠΎΠΌ – ΡΡ‚Π΅ΠΏΠ΅Π½ΡŒΡŽ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ мноТСства называСтся мноТСство всСх подмноТСств Π΄Π°Π½Π½ΠΎΠ³ΠΎ мноТСства. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ссли Ρƒ нас Π΅ΡΡ‚ΡŒ мноТСство Π²Ρ€ΠΎΠ΄Π΅ [1,2,3], Π΅Π³ΠΎ мноТСство-ΡΡ‚Π΅ΠΏΠ΅Π½ΡŒ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ мноТСства:

[1,2,3]

[1,2]

[1,3]

[1]

[2,3]

[2]

[3]

[]

Π”Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ мноТСства-стСпСни ΠΏΠΎΡ…ΠΎΠΆΠ΅ Π½Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ всСх сочСтаний сохранСния ΠΈ выбрасывания элСмСнтов ΠΈΠ· мноТСства. НапримСр, [2,3] – это исходноС мноТСство с ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ числа 1; [1,2] – это исходноС мноТСство с ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ числа 3 ΠΈ Ρ‚. Π΄.

Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ мноТСство-ΡΡ‚Π΅ΠΏΠ΅Π½ΡŒ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Ρ‚ΠΎ списка, ΠΌΡ‹ полоТимся Π½Π° Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ. ΠœΡ‹ Π±Π΅Ρ€Ρ‘ΠΌ список [1,2,3], Π° Π·Π°Ρ‚Π΅ΠΌ смотрим Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ элСмСнт, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π²Π΅Π½ 1, ΠΈ ΡΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ сСбя: Β«Π”ΠΎΠ»ΠΆΠ½Ρ‹ Π»ΠΈ ΠΌΡ‹ Π΅Π³ΠΎ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΈΠ»ΠΈ ΠΎΡ‚Π±Ρ€ΠΎΡΠΈΡ‚ΡŒ?Β» Ну, Π½Π° самом Π΄Π΅Π»Π΅ ΠΌΡ‹ Ρ…ΠΎΡ‚Π΅Π»ΠΈ Π±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΈ Ρ‚ΠΎ ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ΅. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΌΡ‹ ΠΎΡ‚Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΡƒΠ΅ΠΌ список ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ сохраняСт ΠΈ отбрасываСт ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ элСмСнт ΠΈΠ· списка Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎ. Π’ΠΎΡ‚ наша функция powerset:

powerset :: [a] –> [[a]]

powerset xs = filterM (\x –> [True, False]) xs

Π‘Ρ‚ΠΎΠΏ, это всё?! Π£Π³Ρƒ! ΠœΡ‹ Ρ€Π΅ΡˆΠ°Π΅ΠΌ ΠΎΡ‚Π±Ρ€ΠΎΡΠΈΡ‚ΡŒ ΠΈ ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ элСмСнт нСзависимо ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ собой прСдставляСт. Π£ нас Π΅ΡΡ‚ΡŒ Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚, поэтому Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ список Ρ‚ΠΎΠΆΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ – ΠΈ ΠΏΠΎΡ‚ΠΎΠΌΡƒ Π±ΡƒΠ΄Π΅Ρ‚ списком списков. Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ:

ghci> powerset [1,2,3]

[[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]]

Π’Π°ΠΌ потрСбуСтся Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡ€Π°Π·ΠΌΡ‹ΡΠ»ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ½ΡΡ‚ΡŒ это. ΠŸΡ€ΠΎΡΡ‚ΠΎ воспринимайтС списки ΠΊΠ°ΠΊ Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ значСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚ΠΎΠ»ΠΊΠΎΠΌ Π½Π΅ Π·Π½Π°ΡŽΡ‚, Ρ‡Π΅ΠΌ Π±Ρ‹Ρ‚ΡŒ, поэтому Ρ€Π΅ΡˆΠ°ΡŽΡ‚ Π±Ρ‹Ρ‚ΡŒ сразу всСм, – ΠΈ эту ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΡŽ станСт ΠΏΡ€ΠΎΡ‰Π΅ ΡƒΡΠ²ΠΎΠΈΡ‚ΡŒ!

Ѐункция foldM

ΠœΠΎΠ½Π°Π΄ΠΈΡ‡Π΅ΡΠΊΠΈΠΌ Π°Π½Π°Π»ΠΎΠ³ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ foldl являСтся функция foldM. Если Π²Ρ‹ ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅ свои свёртки ΠΈΠ· Π³Π»Π°Π²Ρ‹ 5, Π²Ρ‹ Π·Π½Π°Π΅Ρ‚Π΅, Ρ‡Ρ‚ΠΎ функция foldl ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π±ΠΈΠ½Π°Ρ€Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, исходный аккумулятор ΠΈ сворачиваСмый список, Π° Π·Π°Ρ‚Π΅ΠΌ сворачиваСт Π΅Π³ΠΎ слСва Π² ΠΎΠ΄Π½ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Π±ΠΈΠ½Π°Ρ€Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. Ѐункция foldM Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‚ΠΎ ΠΆΠ΅ самоС, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ½Π° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π±ΠΈΠ½Π°Ρ€Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΡΡ‰ΡƒΡŽ монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΈ сворачиваСт список с Π΅Ρ‘ использованиСм. ΠΠ΅ΡƒΠ΄ΠΈΠ²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, Ρ‡Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠΆΠ΅ являСтся монадичСским. Π’ΠΈΠΏ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ foldl Ρ‚Π°ΠΊΠΎΠ²: