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

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

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

import Data.List


main = do

   contents <– getContents

   let threes = groupsOf 3 (map read $ lines contents)

       roadSystem = map (\[a,b,c] –> Section a b c) threes

       path = optimalPath roadSystem

       pathString = concat $ map (show . fst) path

       pathTime = sum $ map snd path

   putStrLn $ "Π›ΡƒΡ‡ΡˆΠΈΠΉ ΠΏΡƒΡ‚ΡŒ: " ++ pathString

   putStrLn $ "ВрСмя: " ++ show pathTime

Π’Π½Π°Ρ‡Π°Π»Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ со стандартного Π²Ρ…ΠΎΠ΄Π°. Π—Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ lines с ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ строку Π²ΠΈΠ΄Π° "50\n10\n30\n… Π² список ["50","10","30"…, ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ map read, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ строки ΠΈΠ· списка Π² числа. Π’Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ groupsOf 3, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ список списков Π΄Π»ΠΈΠ½ΠΎΠΉ 3. ΠŸΡ€ΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ (\[a,b,c] –> Section a b c) ΠΊ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠΌΡƒ списку списков. Как ΠΌΡ‹ Π²ΠΈΠ΄ΠΈΠΌ, данная анонимная функция ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ список ΠΈΠ· Ρ‚Ρ€Ρ‘Ρ… элСмСнтов ΠΈ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π΅Π³ΠΎ Π² ΡΠ΅ΠΊΡ†ΠΈΡŽ. Π’ ΠΈΡ‚ΠΎΠ³Π΅ roadSystem содСрТит систСму Π΄ΠΎΡ€ΠΎΠ³ ΠΈ ΠΈΠΌΠ΅Π΅Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ RoadSystem (ΠΈΠ»ΠΈ [Section]). Π”Π°Π»Π΅Π΅ ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ optimalPath, ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΏΡƒΡ‚ΡŒ ΠΈ ΠΎΠ±Ρ‰Π΅Π΅ врСмя Π² ΡƒΠ΄ΠΎΠ±Π½ΠΎΠΉ тСкстовой Ρ„ΠΎΡ€ΠΌΠ΅, ΠΈ распСчатываСм ΠΈΡ….

Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ тСкст:

50

10

30

5

90

20

40

2

25

10

8

0

Π² Ρ„Π°ΠΉΠ»Π΅ paths.txt ΠΈ Π·Π°Ρ‚Π΅ΠΌ «скормим» Π΅Π³ΠΎ нашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅.

$ ./heathrow < paths.txt

Π›ΡƒΡ‡ΡˆΠΈΠΉ ΠΏΡƒΡ‚ΡŒ: BCACBBC

ВрСмя: 75

ΠžΡ‚Π»ΠΈΡ‡Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚!

ΠœΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Data.Random, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Π΄Π»ΠΈΠ½Π½Ρ‹Π΅ систСмы Π΄ΠΎΡ€ΠΎΠ³ ΠΈ Β«ΡΠΊΠΎΡ€ΠΌΠΈΡ‚ΡŒΒ» ΠΈΡ… Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ написанной ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅. Если Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ стСка, ΠΏΠΎΠΏΡ‹Ρ‚Π°ΠΉΡ‚Π΅ΡΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ foldl' вмСсто foldl ΠΈ foldl' (+) 0 вмСсто sum. МоТно Ρ‚Π°ΠΊΠΆΠ΅ ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

$ ghc -0 heathrow.hs

Π£ΠΊΠ°Π·Π°Π½ΠΈΠ΅ Ρ„Π»Π°Π³Π° 0 Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ, которая ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ стСка Π² Ρ‚Π°ΠΊΠΈΡ… функциях, ΠΊΠ°ΠΊ foldl ΠΈ sum.

11

АппликативныС Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Ρ‹

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

ΠšΠ»Π°ΡΡΡ‹ Ρ‚ΠΈΠΏΠΎΠ² ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ – это ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ собствСнный Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΎΠ±Π΄ΡƒΠΌΠ°Ρ‚ΡŒ, ΠΊΠ°ΠΊ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ, ΠΈ ΡΠ²ΡΠ·Π°Ρ‚ΡŒ Π΅Π³ΠΎ с классами Ρ‚ΠΈΠΏΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ Π΅Π³ΠΎ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅. Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ввСсти Π½ΠΎΠ²Ρ‹ΠΉ класс Ρ‚ΠΈΠΏΠΎΠ², Π° Π·Π°Ρ‚Π΅ΠΌ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΡƒΠΆΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Ρ‚ΠΈΠΏΡ‹ Π΅Π³ΠΎ экзСмплярами. По этой ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ ΠΈ благодаря прСкрасной систСмС Ρ‚ΠΈΠΏΠΎΠ² языка Haskell, которая позволяСт Π½Π°ΠΌ Π·Π½Π°Ρ‚ΡŒ ΠΌΠ½ΠΎΠ³ΠΎΠ΅ ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎ Π΅Ρ‘ объявлСнию Ρ‚ΠΈΠΏΠ°, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ классы Ρ‚ΠΈΠΏΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ ΠΎΡ‡Π΅Π½ΡŒ ΠΎΠ±Ρ‰Π΅Π΅, абстрактноС ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅.

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

Π€ΡƒΠ½ΠΊΡ‚ΠΎΡ€Ρ‹ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ

Как Π²Ρ‹ ΡƒΠ·Π½Π°Π»ΠΈ ΠΈΠ· Π³Π»Π°Π²Ρ‹ 7, Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Ρ‹ – это сущности, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, списки, значСния Ρ‚ΠΈΠΏΠ° Maybe ΠΈ Π΄Π΅Ρ€Π΅Π²ΡŒΡ. Π’ языкС Haskell ΠΎΠ½ΠΈ ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ классом Ρ‚ΠΈΠΏΠΎΠ² Functor, содСрТащим Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΌΠ΅Ρ‚ΠΎΠ΄ fmap. Ѐункция fmap ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ fmap :: (a –> b) –> f a –> f b, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚: Β«Π”Π°ΠΉΡ‚Π΅ ΠΌΠ½Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ a ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ b ΠΈ ΠΊΠΎΡ€ΠΎΠ±ΠΊΡƒ, Π³Π΄Π΅ содСрТится a (ΠΈΠ»ΠΈ нСсколько a), ΠΈ я Π²Π΅Ρ€Π½Ρƒ ΠΊΠΎΡ€ΠΎΠ±ΠΊΡƒ с b (ΠΈΠ»ΠΈ нСсколькими b) Π²Π½ΡƒΡ‚Ρ€ΠΈΒ». Она примСняСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΊ элСмСнту Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ.

ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ значСния Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€ΠΎΠ² ΠΊΠ°ΠΊ значСния с Π΄ΠΎΠ±Π°Π²ΠΎΡ‡Π½Ρ‹ΠΌ контСкстом. НапримСр, значСния Ρ‚ΠΈΠΏΠ° Maybe ΠΎΠ±Π»Π°Π΄Π°ΡŽΡ‚ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ контСкстом Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ вычислСния ΠΌΠΎΠ³Π»ΠΈ ΠΎΠΊΠΎΠ½Ρ‡ΠΈΡ‚ΡŒΡΡ Π½Π΅ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ. По ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡŽ ΠΊ спискам контСкстом являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ мноТСствСнным Π»ΠΈΠ±ΠΎ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ. Ѐункция fmap примСняСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ, сохраняя Π΅Π³ΠΎ контСкст.

Если ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ конструктор Ρ‚ΠΈΠΏΠ° экзСмпляром класса Functor, ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ сорт * –> *; это Π·Π½Π°Ρ‡ΠΈΡ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ½ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ€ΠΎΠ²Π½ΠΎ ΠΎΠ΄ΠΈΠ½ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΉ Ρ‚ΠΈΠΏ Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Ρ‚ΠΈΠΏΠ°. НапримСр, конструктор Maybe ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ сдСлан экзСмпляром, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° для произвСдСния ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°, ΠΊΠ°ΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Maybe Int ΠΈΠ»ΠΈ Maybe String. Если конструктор Ρ‚ΠΈΠΏΠ° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π΄Π²Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°, ΠΊΠ°ΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, конструктор Either, ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ частично ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ конструктор Ρ‚ΠΈΠΏΠ° Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΎΠ½ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Functor Either where, Π·Π°Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Functor (Either a) where. Π—Π°Ρ‚Π΅ΠΌ, Ссли Π±Ρ‹ ΠΌΡ‹ Π²ΠΎΠΎΠ±Ρ€Π°Π·ΠΈΠ»ΠΈ, Ρ‡Ρ‚ΠΎ функция fmap ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ со значСниями Ρ‚ΠΈΠΏΠ° Either a, ΠΎΠ½Π° ΠΈΠΌΠ΅Π»Π° Π±Ρ‹ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ описаниС Ρ‚ΠΈΠΏΠ°:

fmap :: (b –> c) –> Either a b –> Either a c

Как Π²ΠΈΠ΄ΠΈΡ‚Π΅, Ρ‡Π°ΡΡ‚ΡŒ Either a – фиксированная, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ частично ΠΏΡ€ΠΈΠΌΠ΅Π½Ρ‘Π½Π½Ρ‹ΠΉ конструктор Ρ‚ΠΈΠΏΠ° Either a ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ°.

ДСйствия Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° Π² качСствС Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€ΠΎΠ²

К настоящСму ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρƒ Π²Ρ‹ ΠΈΠ·ΡƒΡ‡ΠΈΠ»ΠΈ, ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ Ρ‚ΠΈΠΏΡ‹ (Ссли Π±Ρ‹Ρ‚ΡŒ Ρ‚ΠΎΡ‡Π½Ρ‹ΠΌ, конструкторы Ρ‚ΠΈΠΏΠΎΠ²) ΡΠ²Π»ΡΡŽΡ‚ΡΡ экзСмплярами класса Functor: [] ΠΈ Maybe, Either a, Ρ€Π°Π²Π½ΠΎ ΠΊΠ°ΠΊ ΠΈ Ρ‚ΠΈΠΏ Tree, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ создали Π² Π³Π»Π°Π²Π΅ 7. Π’Ρ‹ Π²ΠΈΠ΄Π΅Π»ΠΈ, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ ΠΈΡ… с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π½Π° всСобщСС Π±Π»Π°Π³ΠΎ. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π°Π²Π°ΠΉΡ‚Π΅ взглянСм Π½Π° экзСмпляр Ρ‚ΠΈΠΏΠ° IO.

Если ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚, скаТСм, Ρ‚ΠΈΠΏΠΎΠΌ IO String, это ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°ΠΌΠΈ дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π²Ρ‹ΠΉΠ΄Π΅Ρ‚ Π² Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠΈΡ€ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ для нас Π½Π΅ΠΊΡƒΡŽ строку, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π·Π°Ρ‚Π΅ΠΌ Π²Π΅Ρ€Π½Ρ‘Ρ‚ Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°. ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ запись <– Π² синтаксисС do для привязывания этого Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΊ ΠΈΠΌΠ΅Π½ΠΈ. Π’ Π³Π»Π°Π²Π΅ 8 ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΈ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ дСйствия Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° ΠΏΠΎΡ…ΠΎΠΆΠΈ Π½Π° ящики с малСнькими Π½ΠΎΠΆΠΊΠ°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ выходят Π½Π°Ρ€ΡƒΠΆΡƒ ΠΈ приносят Π½Π°ΠΌ ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· внСшнСго ΠΌΠΈΡ€Π°. ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ принСсли, Π½ΠΎ послС просмотра Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ снова ΠΎΠ±Π΅Ρ€Π½ΡƒΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² Ρ‚ΠΈΠΏ IO. Рассматривая эту аналогию с ящиками Π½Π° Π½ΠΎΠΆΠΊΠ°Ρ…, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Ρ‚ΠΈΠΏ IO дСйствуСт ΠΊΠ°ΠΊ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€.

Π”Π°Π²Π°ΠΉΡ‚Π΅ посмотрим, ΠΊΠ°ΠΊ ΠΆΠ΅ это Ρ‚ΠΈΠΏ IO являСтся экзСмпляром класса Functor… Когда ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ fmap для отобраТСния дСйствия Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‚ΠΎ ΠΆΠ΅ самоС, Π½ΠΎ ΠΊ Π΅Π³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ примСняСтся наша функция. Π’ΠΎΡ‚ ΠΊΠΎΠ΄:

instance Functor IO where

   fmap f action = do

      result <– action

      return (f result)

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ отобраТСния дСйствия Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ‡Π΅Π³ΠΎ-Π»ΠΈΠ±ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ сразу ΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ синтаксис do для склСивания Π΄Π²ΡƒΡ… дСйствий ΠΈ создания ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ. Π’ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ для ΠΌΠ΅Ρ‚ΠΎΠ΄Π° fmap ΠΌΡ‹ создаём Π½ΠΎΠ²ΠΎΠ΅ дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ сначала выполняСт ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, давая Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρƒ имя result. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ выполняСм return (f result). ВспомнитС, Ρ‡Ρ‚ΠΎ return – это функция, ΡΠΎΠ·Π΄Π°ΡŽΡ‰Π°Ρ дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ‚, Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‡Ρ‚ΠΎ-Π»ΠΈΠ±ΠΎ Π² качСствС своСго Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°.

ДСйствиС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ Π±Π»ΠΎΠΊ do, Π±ΡƒΠ΄Π΅Ρ‚ всСгда Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ своСго послСднСго дСйствия. Π’ΠΎΡ‚ ΠΏΠΎΡ‡Π΅ΠΌΡƒ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ return, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ дСйствиС Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π² Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ‚, Π° просто Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ f result Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° Π½ΠΎΠ²ΠΎΠ³ΠΎ дСйствия Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°. ВзглянитС Π½Π° этот кусок ΠΊΠΎΠ΄Π°:

main = do

   line <– getLine

   let line' = reverse line

   putStrLn $ "Π’Ρ‹ сказали " ++ line' ++ " Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚!"

   putStrLn $ "Π”Π°, Π²Ρ‹ Ρ‚ΠΎΡ‡Π½ΠΎ сказали " ++ line' ++ " Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚!"

Π£ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ строка, ΠΈ ΠΌΡ‹ ΠΎΡ‚Π΄Π°Ρ‘ΠΌ Π΅Ρ‘ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ, Π½ΠΎ Π² ΠΏΠ΅Ρ€Π΅Π²Ρ‘Ρ€Π½ΡƒΡ‚ΠΎΠΌ Π²ΠΈΠ΄Π΅. А Π²ΠΎΡ‚ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ это с использованиСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fmap: