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

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

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

Бписки

Бписки (Π½Π° самом Π΄Π΅Π»Π΅ конструктор Ρ‚ΠΈΠΏΠ° списка, []) ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Π°ΠΌΠΈ. Π’ΠΎΡ‚ Ρ‚Π°ΠΊ ΡΡŽΡ€ΠΏΡ€ΠΈΠ·! Π’ΠΎΡ‚ ΠΊΠ°ΠΊ [] являСтся экзСмпляром класса Applicative:

instance Applicative [] where

   pure x = [x]

   fs <*> xs = [f x | f <– fs, x <– xs]

ВспомнитС, Ρ‡Ρ‚ΠΎ функция pure ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π΅Π³ΠΎ Π² контСкст ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Π”Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, ΠΎΠ½Π° ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π΅Π³ΠΎ Π² ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ контСкст, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ всё Π΅Ρ‰Ρ‘ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. ΠœΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ контСкстом для списков Π±Ρ‹Π» Π±Ρ‹ пустой список, Π½ΠΎ пустой список ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ отсутствиС значСния, поэтому ΠΎΠ½ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π² сСбС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΌΡ‹ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠ»ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pure. Π’ΠΎΡ‚ ΠΏΠΎΡ‡Π΅ΠΌΡƒ эта функция ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π΅Π³ΠΎ Π² одноэлСмСнтный список. ΠŸΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ контСкстом для Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Π° Maybe Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Nothing – Π½ΠΎ ΠΎΠ½ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ отсутствиС значСния вмСсто самого значСния, поэтому функция pure Π² Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ экзСмпляра для Ρ‚ΠΈΠΏΠ° Maybe Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° ΠΊΠ°ΠΊ Π²Ρ‹Π·ΠΎΠ² конструктора Π΄Π°Π½Π½Ρ‹Ρ… Just.

Π’ΠΎΡ‚ функция pure Π² дСйствии:

ghci> pure "Π­ΠΉ" :: [String]

["Π­ΠΉ"]

ghci> pure "Π­ΠΉ" :: Maybe String

Just "Π­ΠΉ"

Π§Ρ‚ΠΎ насчёт ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° <*>? Если Π±Ρ‹ Ρ‚ΠΈΠΏ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° <*> ограничивался Ρ‚ΠΎΠ»ΡŒΠΊΠΎ списками, ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ Π±Ρ‹ (<*>) :: [a –> b] –> [a] –> [b]. Π­Ρ‚ΠΎΡ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Ρ‡Π΅Ρ€Π΅Π· Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ списков. Он Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΊΠ°ΠΊΠΈΠΌ-Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈΠ· своСго Π»Π΅Π²ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°, Π° Π·Π°Ρ‚Π΅ΠΌ с Π΅Ρ‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΡ‚ΡŒ ΠΏΡ€Π°Π²Ρ‹ΠΉ. Но Π»Π΅Π²Ρ‹ΠΉ список ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π΅ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π² сСбС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈΠ»ΠΈ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ ΠΎΠ΄Π½Ρƒ Π»ΠΈΠ±ΠΎ нСсколько Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Π° ΠΏΡ€Π°Π²Ρ‹ΠΉ список Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ нСсколько Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ. Π’ΠΎΡ‚ ΠΏΠΎΡ‡Π΅ΠΌΡƒ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ списков для извлСчСния ΠΈΠ· ΠΎΠ±ΠΎΠΈΡ… списков. ΠœΡ‹ примСняСм ΠΊΠ°ΠΆΠ΄ΡƒΡŽ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈΠ· Π»Π΅Π²ΠΎΠ³ΠΎ списка ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΌΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ ΠΈΠ· ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ список содСрТит всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΈ примСнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ· Π»Π΅Π²ΠΎΠ³ΠΎ списка ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ ΠΈΠ· ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ.

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ <*> со списками Π²ΠΎΡ‚ Ρ‚Π°ΠΊ:

ghci> [(*0),(+100),( 2)] <*> [1,2,3]

[0,0,0,101,102,103,1,4,9]

Π›Π΅Π²Ρ‹ΠΉ список содСрТит Ρ‚Ρ€ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π° ΠΏΡ€Π°Π²Ρ‹ΠΉ – Ρ‚Ρ€ΠΈ значСния, поэтому Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ спискС Π±ΡƒΠ΄Π΅Ρ‚ Π΄Π΅Π²ΡΡ‚ΡŒ элСмСнтов. КаТдая функция ΠΈΠ· Π»Π΅Π²ΠΎΠ³ΠΎ списка примСняСтся ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ элСмСнту ΠΈΠ· ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ. Если Ρƒ нас имССтся список Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΡ… Π΄Π²Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°, Ρ‚ΠΎ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ двумя списками.

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ двумя списками:

ghci> [(+),(*)] <*> [1,2] <*> [3,4]

[4,5,5,6,3,4,6,8]

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ <*> лСвоассоциативСн, поэтому сначала выполняСтся [(+),(*)] <*> [1,2], Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ Ρ‡Π΅Π³ΠΎ являСтся Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅ список, ΠΊΠ°ΠΊ [(1+),(2+),(1*),(2*)], ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ каТдая функция слСва примСняСтся ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ справа. Π—Π°Ρ‚Π΅ΠΌ выполняСтся [(1+),(2+),(1*),(2*)] <*> [3,4], Ρ‡Ρ‚ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚.

Как Π·Π΄ΠΎΡ€ΠΎΠ²ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ ΡΡ‚ΠΈΠ»ΡŒ со списками!

ghci> (++) <$> ["Ρ…a","Ρ…eΡ…","Ρ…ΠΌ"] <*> ["?","!","."]

["Ρ…a?","Ρ…a!","Ρ…a.","Ρ…eΡ…?","Ρ…eΡ…!","Ρ…eΡ….","Ρ…ΠΌ?","Ρ…ΠΌ!","Ρ…ΠΌ."]

Π•Ρ‰Ρ‘ Ρ€Π°Π·: ΠΌΡ‹ использовали ΠΎΠ±Ρ‹Ρ‡Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΡƒΡŽ Π΄Π²Π΅ строки, ΠΌΠ΅ΠΆΠ΄Ρƒ двумя списками строк, просто вставляя ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹.

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ списки ΠΊΠ°ΠΊ Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ вычислСния. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²Ρ€ΠΎΠ΄Π΅ 100 ΠΈΠ»ΠΈ "Ρ‡Ρ‚ΠΎ" ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ вычислСниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚. Π’ Ρ‚ΠΎ ΠΆΠ΅ врСмя список Π²Ρ€ΠΎΠ΄Π΅ [1,2,3] ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ вычислСниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½Π΅ Π² состоянии ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒΡΡ, ΠΊΠ°ΠΊΠΎΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΎΠ½ΠΎ ΠΆΠ΅Π»Π°Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ, поэтому Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½Π°ΠΌ всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ (+) <$> [1,2,3] <*> [4,5,6], Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ это ΠΊΠ°ΠΊ объСдинСниС Π΄Π²ΡƒΡ… Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… вычислСний с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° + Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π΅Ρ‰Ρ‘ ΠΎΠ΄Π½ΠΎ Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ вычислСниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π΅Ρ‰Ρ‘ мСньшС ΡƒΠ²Π΅Ρ€Π΅Π½ΠΎ Π² своём Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅.

ИспользованиС Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ стиля со списками часто являСтся Ρ…ΠΎΡ€ΠΎΡˆΠ΅ΠΉ Π·Π°ΠΌΠ΅Π½ΠΎΠΉ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌ списков. Π’ Π³Π»Π°Π²Π΅ 1 ΠΌΡ‹ Ρ…ΠΎΡ‚Π΅Π»ΠΈ вывСсти всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΠΉ [2,5,10] ΠΈ [8,10,11] ΠΈ с этой Ρ†Π΅Π»ΡŒΡŽ прСдприняли ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅:

ghci> [x*y | x <– [2,5,10], y <– [8,10,11]]

[16,20,22,40,50,55,80,100,110]

ΠœΡ‹ просто ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ значСния ΠΈΠ· ΠΎΠ±ΠΎΠΈΡ… списков ΠΈ примСняСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠ΅ΠΉ элСмСнтов. Π’ΠΎ ΠΆΠ΅ самоС ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΈ Π² Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½ΠΎΠΌ стилС:

ghci> (*) <$> [2,5,10] <*> [8,10,11]

[16,20,22,40,50,55,80,100,110]

Для мСня Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ понятСн, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΡ€ΠΎΡ‰Π΅ ΠΏΠΎΠ½ΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ просто Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ * ΠΌΠ΅ΠΆΠ΄Ρƒ двумя Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌΠΈ вычислСниями. Если Π±Ρ‹ ΠΌΡ‹ Π·Π°Ρ…ΠΎΡ‚Π΅Π»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ произвСдСния элСмСнтов, Π±ΠΎΠ»ΡŒΡˆΠΈΡ… 50, ΠΌΡ‹ Π±Ρ‹ использовали ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅:

ghci> filter (>50) $ (*) <$> [2,5,10] <*> [8,10,11]

[55,80,100,110]

Π›Π΅Π³ΠΊΠΎ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π²Ρ‹Π·ΠΎΠ² выраТСния pure f <*> xs ΠΏΡ€ΠΈ использовании списков эквивалСнтСн Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΡŽ fmap f xs. Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ вычислСния pure f – это просто [f], Π° Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ [f] <*> xs ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π² Π»Π΅Π²ΠΎΠΌ спискС ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ Π² ΠΏΡ€Π°Π²ΠΎΠΌ; Π½ΠΎ Π² Π»Π΅Π²ΠΎΠΌ спискС Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Π° функция, ΠΈ, ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, это ΠΏΠΎΡ…ΠΎΠΆΠ΅ Π½Π° ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅.

Π’ΠΈΠΏ IO – Ρ‚ΠΎΠΆΠ΅ Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€

Π”Ρ€ΡƒΠ³ΠΎΠΉ экзСмпляр класса Applicative, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΌΡ‹ ΡƒΠΆΠ΅ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°Π»ΠΈΡΡŒ, – экзСмпляр для Ρ‚ΠΈΠΏΠ° IO. Π’ΠΎΡ‚ ΠΊΠ°ΠΊ ΠΎΠ½ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½:

instance Applicative IO where

   pure = return

   a <*> b = do

      f <– a

      x <– b

      return (f x)

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΡΡƒΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pure состоит Π² ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ значСния Π² ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ контСкст, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ всё Π΅Ρ‰Ρ‘ содСрТит Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠ°ΠΊ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ, Ρ‡Ρ‚ΠΎ Π² случаС с Ρ‚ΠΈΠΏΠΎΠΌ IO функция pure – это просто Π²Ρ‹Π·ΠΎΠ² return. Ѐункция return создаёт дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ‚. Оно просто Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½Π΅ΠΊΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² качСствС своСго Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, Π½Π΅ производя Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° Π²Ρ€ΠΎΠ΄Π΅ ΠΏΠ΅Ρ‡Π°Ρ‚ΠΈ Π½Π° Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π» ΠΈΠ»ΠΈ чтСния ΠΈΠ· Ρ„Π°ΠΉΠ»Π°.



Если Π±Ρ‹ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ <*> ограничивался Ρ€Π°Π±ΠΎΡ‚ΠΎΠΉ с Ρ‚ΠΈΠΏΠΎΠΌ IO, ΠΎΠ½ Π±Ρ‹ ΠΈΠΌΠ΅Π» Ρ‚ΠΈΠΏ (<*>) :: IO (a –> b) –> IO a –> IO b. Π’ случаС с Ρ‚ΠΈΠΏΠΎΠΌ IO ΠΎΠ½ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° a, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, выполняСт дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° ΠΈ связываСт эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ с ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠΌ f. Π—Π°Ρ‚Π΅ΠΌ ΠΎΠ½ выполняСт дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° b ΠΈ связываСт Π΅Π³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ с ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠΌ x. НаконСц, ΠΎΠ½ примСняСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ f ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ x ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ этого примСнСния Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°. Π§Ρ‚ΠΎΠ±Ρ‹ это Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ, ΠΌΡ‹ использовали здСсь синтаксис do. (ВспомнитС, Ρ‡Ρ‚ΠΎ ΡΡƒΡ‚ΡŒ синтаксиса do Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Π·ΡΡ‚ΡŒ нСсколько дСйствий Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° ΠΈ Β«ΡΠΊΠ»Π΅ΠΈΡ‚ΡŒΒ» ΠΈΡ… Π² ΠΎΠ΄Π½ΠΎ.)

ΠŸΡ€ΠΈ использовании Ρ‚ΠΈΠΏΠΎΠ² Maybe ΠΈ [] ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ <*> просто ΠΊΠ°ΠΊ ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ· Π΅Ρ‘ Π»Π΅Π²ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π΅Ρ‘ ΠΊ ΠΏΡ€Π°Π²ΠΎΠΌΡƒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρƒ. Π’ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠΈ Ρ‚ΠΈΠΏΠ° IO ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ остаётся Π² силС, Π½ΠΎ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Ρƒ нас появляСтся понятиС помСщСния Π² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΡ‹ Π±Π΅Ρ€Ρ‘ΠΌ Π΄Π²Π° дСйствия Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° ΠΈ «склСиваСм» ΠΈΡ… Π² ΠΎΠ΄Π½ΠΎ. ΠœΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈΠ· ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ дСйствия Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, Π½ΠΎ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΈΠ· дСйствия Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, послСднСС Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ. РассмотритС Π²ΠΎΡ‚ это:

myAction :: IO String

myAction = do

   a <– getLine

   b <– getLine

   return $ a ++ b

Π­Ρ‚ΠΎ дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ запросит Ρƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π΄Π²Π΅ строки ΠΈ Π²Π΅Ρ€Π½Ρ‘Ρ‚ Π² качСствС своСго Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΈΡ… ΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½Π°Ρ†ΠΈΡŽ. ΠœΡ‹ достигли этого благодаря «склСиванию» Π΄Π²ΡƒΡ… дСйствий Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° getLine ΠΈ return, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΡ‹ Ρ…ΠΎΡ‚Π΅Π»ΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ нашС Π½ΠΎΠ²ΠΎΠ΅ «склССнноС» дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° содСрТало Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния a ++ b. Π•Ρ‰Ρ‘ ΠΎΠ΄ΠΈΠ½ способ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ это состоит Π² использовании Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ стиля:

myAction :: IO String

myAction = (++) <$> getLine <*> getLine

Π­Ρ‚ΠΎ Ρ‚ΠΎ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΄Π΅Π»Π°Π»ΠΈ Ρ€Π°Π½Π΅Π΅, ΠΊΠΎΠ³Π΄Π° создавали дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ примСняло Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°ΠΌΠΈ Π΄Π²ΡƒΡ… Π΄Ρ€ΡƒΠ³ΠΈΡ… дСйствий Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°. ВспомнитС, Ρ‡Ρ‚ΠΎ функция getLine – это дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ getLine :: IO String. Когда ΠΌΡ‹ примСняСм ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ <*> ΠΌΠ΅ΠΆΠ΄Ρƒ двумя Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ значСниями, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ являСтся Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ всё это ΠΈΠΌΠ΅Π΅Ρ‚ смысл.

Если ΠΌΡ‹ вСрнёмся ΠΊ Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ с ΠΊΠΎΡ€ΠΎΠ±ΠΊΠ°ΠΌΠΈ, Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ сСбС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ getLine ΠΊΠ°ΠΊ ΠΊΠΎΡ€ΠΎΠ±ΠΊΡƒ, которая Π²Ρ‹ΠΉΠ΄Π΅Ρ‚ Π² Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠΈΡ€ ΠΈ принСсёт Π½Π°ΠΌ строку. Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ выраТСния (++) <$> getLine <*> getLine создаёт Π΄Ρ€ΡƒΠ³ΡƒΡŽ, Π±ΠΎΜΠ»ΡŒΡˆΡƒΡŽ ΠΊΠΎΡ€ΠΎΠ±ΠΊΡƒ, которая посылаСт эти Π΄Π²Π΅ ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ Π½Π°Ρ€ΡƒΠΆΡƒ для получСния строк с Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°, Π° ΠΏΠΎΡ‚ΠΎΠΌ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½Π°Ρ†ΠΈΡŽ этих Π΄Π²ΡƒΡ… строк Π² качСствС своСго Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°.