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

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

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

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ класса. Оно Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏ Maybe являСтся ΠΌΠΎΠ½ΠΎΠΈΠ΄ΠΎΠΌ, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли для Ρ‚ΠΈΠΏΠ° a ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½ экзСмпляр класса Monoid. Если ΠΌΡ‹ объСдиняСм Π½Π΅Ρ‡Ρ‚ΠΎ со Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Nothing, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ mappend, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ являСтся это Π½Π΅Ρ‡Ρ‚ΠΎ. Если ΠΌΡ‹ объСдиняСм Π΄Π²Π° значСния Just с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ mappend, Ρ‚ΠΎ содСрТимоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Just ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π° Π·Π°Ρ‚Π΅ΠΌ оборачиваСтся ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π² конструктор Just. ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ это, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ класса Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏ значСния, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ находится Π²Π½ΡƒΡ‚Ρ€ΠΈ Just, ΠΈΠΌΠ΅Π΅Ρ‚ экзСмпляр класса Monoid.

ghci> Nothing `mappend` Just "Π°Π½Π΄Ρ€Π΅ΠΉ"

Just "Π°Π½Π΄Ρ€Π΅ΠΉ"

ghci> Just LT `mappend` Nothing

Just LT

ghci> Just (Sum 3) `mappend` Just (Sum 4)

Just (Sum {getSum = 7})

Π­Ρ‚ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ ΠΈΠΌΠ΅Π΅ΠΌ Π΄Π΅Π»ΠΎ с ΠΌΠΎΠ½ΠΎΠΈΠ΄Π°ΠΌΠΈ ΠΊΠ°ΠΊ с Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°ΠΌΠΈ вычислСний, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³Π»ΠΈ ΠΎΠΊΠΎΠ½Ρ‡ΠΈΡ‚ΡŒΡΡ Π½Π΅ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ. Из-Π·Π° наличия этого экзСмпляра Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ, ΠΎΠΊΠΎΠ½Ρ‡ΠΈΠ»ΠΈΡΡŒ Π»ΠΈ вычислСния Π½Π΅ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, опрСдСляя, Π²Π΅Ρ€Π½ΡƒΠ»ΠΈ ΠΎΠ½ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Nothing ΠΈΠ»ΠΈ Just; ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ просто ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΡ… ΠΊΠ°ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ ΠΌΠΎΠ½ΠΎΠΈΠ΄Ρ‹.

Но Ρ‡Ρ‚ΠΎ Ссли Ρ‚ΠΈΠΏ содСрТимого Ρ‚ΠΈΠΏΠ° Maybe Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ экзСмпляра класса Monoid? ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ объявлСнии экзСмпляра СдинствСнный случай, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ содСрТимыС ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΌΠΎΠ½ΠΎΠΈΠ΄Π°ΠΌΠΈ, – это ΠΊΠΎΠ³Π΄Π° ΠΎΠ±Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ mappend ΠΎΠ±Ρ‘Ρ€Π½ΡƒΡ‚Ρ‹ Π² конструктор Just. Когда ΠΌΡ‹ Π½Π΅ Π·Π½Π°Π΅ΠΌ, ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π»ΠΈ содСрТимыС ΠΌΠΎΠ½ΠΎΠΈΠ΄Π°ΠΌΠΈ, ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ mappend ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ; Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΆΠ΅ Π½Π°ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ? Ну, СдинствСнноС, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, – это ΠΎΡ‚Π²Π΅Ρ€Π³Π½ΡƒΡ‚ΡŒ Π²Ρ‚ΠΎΡ€ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π²ΠΎΠ΅. Для этой Ρ†Π΅Π»ΠΈ сущСствуСт Ρ‚ΠΈΠΏ First a. Π’ΠΎΡ‚ Π΅Π³ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅:

newtype First a = First { getFirst :: Maybe a }

   deriving (Eq, Ord, Read, Show)

ΠœΡ‹ Π±Π΅Ρ€Ρ‘ΠΌ Ρ‚ΠΈΠΏ Maybe a ΠΈ ΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ Π΅Π³ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ†ΠΈΠΈ newtype. ЭкзСмпляр класса Monoid Π² Π΄Π°Π½Π½ΠΎΠΌ случаС выглядит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

instance Monoid (Firsta) where

   mempty = First Nothing

   First (Just x) `mappend` _ = First (Just x)

   First Nothing `mappend` x = x

Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ mempty – это просто Nothing, ΠΎΠ±Ρ‘Ρ€Π½ΡƒΡ‚ΠΎΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ конструктора First. Если ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ mappend являСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Just, ΠΌΡ‹ ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌ Π²Ρ‚ΠΎΡ€ΠΎΠΉ. Если ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ – Nothing, Ρ‚ΠΎΠ³Π΄Π° ΠΌΡ‹ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° нСзависимо ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, являСтся Π»ΠΈ ΠΎΠ½ Just ΠΈΠ»ΠΈ Nothing:

ghci> getFirst $ First (Just 'a') `mappend` First (Just 'b')

Just 'a'

ghci> getFirst $ First Nothing `mappend` First (Just 'b')

Just 'b'

ghci> getFirst $ First (Just 'a') `mappend` First Nothing

Just 'a'

Π’ΠΈΠΏ First ΠΏΠΎΠ»Π΅Π·Π΅Π½, ΠΊΠΎΠ³Π΄Π° Ρƒ нас Π΅ΡΡ‚ΡŒ мноТСство Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Ρ‚ΠΈΠΏΠ° Maybe ΠΈ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ Π·Π½Π°Ρ‚ΡŒ, являСтся Π»ΠΈ ΠΊΠ°ΠΊΠΎΠ΅-Π»ΠΈΠ±ΠΎ ΠΈΠ· Π½ΠΈΡ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Just. Для этого годится функция mconcat:

ghci> getFirst . mconcat . map First $ [Nothing, Just 9, Just 10]

Just 9

Если Π½Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ ΠΌΠΎΠ½ΠΎΠΈΠ΄ Π½Π° значСниях Maybe a – Ρ‚Π°ΠΊΠΎΠΉ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ оставался Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ mappend ΡΠ²Π»ΡΡŽΡ‚ΡΡ значСниями Just, Ρ‚ΠΎ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Data.Monoid прСдоставляСт Ρ‚ΠΈΠΏ Last a, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, ΠΊΠ°ΠΊ ΠΈ Ρ‚ΠΈΠΏ First a, Π½ΠΎ ΠΏΡ€ΠΈ объСдинСнии с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ mappend ΠΈ использовании Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ mconcat сохраняСтся послСднСС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π½Π΅ ΡΠ²Π»ΡΡŽΡ‰Π΅Π΅ΡΡ Nothing:

ghci> getLast . mconcat . map Last $ [Nothing, Just 9, Just 10]

Just 10

ghci> getLast $ Last (Just "ΠΎΠ΄ΠΈΠ½") `mappend` Last (Just "Π΄Π²Π°")

Just "two"

Π‘Π²Ρ‘Ρ€Ρ‚ΠΊΠ° Π½Π° ΠΌΠΎΠ½ΠΎΠΈΠ΄Π°Ρ…

Один ΠΈΠ· интСрСсных способов ввСсти ΠΌΠΎΠ½ΠΎΠΈΠ΄Ρ‹ Π² Ρ€Π°Π±ΠΎΡ‚Ρƒ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΈ ΠΏΠΎΠΌΠΎΠ³Π°Π»ΠΈ Π½Π°ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ свёртки Π½Π°Π΄ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ структурами Π΄Π°Π½Π½Ρ‹Ρ…. Π”ΠΎ сих ΠΏΠΎΡ€ ΠΌΡ‹ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠ»ΠΈ свёртки Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π°Π΄ списками, Π½ΠΎ списки – Π½Π΅ СдинствСнная структура Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ²Π΅Ρ€Π½ΡƒΡ‚ΡŒ. ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ свёртки ΠΏΠΎΡ‡Ρ‚ΠΈ Π½Π°Π΄ любой структурой Π΄Π°Π½Π½Ρ‹Ρ…. ОсобСнно Ρ…ΠΎΡ€ΠΎΡˆΠΎ ΠΏΠΎΠ΄Π΄Π°ΡŽΡ‚ΡΡ свёрткС Π΄Π΅Ρ€Π΅Π²ΡŒΡ.

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ сущСствуСт Ρ‚Π°ΠΊ ΠΌΠ½ΠΎΠ³ΠΎ структур Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ…ΠΎΡ€ΠΎΡˆΠΎ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ со свёртками, Π±Ρ‹Π» Π²Π²Π΅Π΄Ρ‘Π½ класс Ρ‚ΠΈΠΏΠΎΠ² Foldable. Подобно Ρ‚ΠΎΠΌΡƒ ΠΊΠ°ΠΊ класс Functor ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для сущностСй, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ, класс Foldable ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для Π²Π΅Ρ‰Π΅ΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ свёрнуты! Π•Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π² ΠΌΠΎΠ΄ΡƒΠ»Π΅ Data.Foldable; ΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½ экспортируСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΈΠΌΠ΅Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΡƒΡŽΡ‚ с ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈΠ· модуля Prelude, Π΅Π³ΠΎ Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, квалифицируя (ΠΈ ΠΏΠΎΠ΄Π°Π²Π°Ρ‚ΡŒ с Π±Π°Π·ΠΈΠ»ΠΈΠΊΠΎΠΌ!):

import qualified Data.Foldable as F

Π§Ρ‚ΠΎΠ±Ρ‹ ΡΡΠΊΠΎΠ½ΠΎΠΌΠΈΡ‚ΡŒ Π΄Ρ€Π°Π³ΠΎΡ†Π΅Π½Π½Ρ‹Π΅ наТатия клавиш, ΠΌΡ‹ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π»ΠΈ Π΅Π³ΠΎ, квалифицируя ΠΊΠ°ΠΊ F.

Π’Π°ΠΊ ΠΊΠ°ΠΊΠΈΠ΅ ΠΈΠ· Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ опрСдСляСт этот класс Ρ‚ΠΈΠΏΠΎΠ²? Π‘Ρ€Π΅Π΄ΠΈ Π½ΠΈΡ… Π΅ΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ foldr, foldl, foldr1 ΠΈ foldl1. Ну ΠΈ?.. ΠœΡ‹ ΡƒΠΆΠ΅ Π΄Π°Π²Π½ΠΎ Π·Π½Π°ΠΊΠΎΠΌΡ‹ с Π½ΠΈΠΌΠΈ! Π§Ρ‚ΠΎ ΠΆ Π² этом Π½ΠΎΠ²ΠΎΠ³ΠΎ? Π”Π°Π²Π°ΠΉΡ‚Π΅ сравним Ρ‚ΠΈΠΏΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ foldr ΠΈΠ· модуля Foldable ΠΈ ΠΎΠ΄Π½ΠΎΠΈΠΌΡ‘Π½Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ· модуля Prelude, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ·Π½Π°Ρ‚ΡŒ, Ρ‡Π΅ΠΌ ΠΎΠ½ΠΈ ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ:

ghci> :t foldr

foldr :: (a –> b –> b) –> b –> [a] –> b

ghci> :t F.foldr

F.foldr :: (F.Foldable t) => (a –> b –> b) –> b –> t a –> b

А-Π°-Π°! Π—Π½Π°Ρ‡ΠΈΡ‚, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ функция foldr ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ список ΠΈ сворачиваСт Π΅Π³ΠΎ, функция foldr ΠΈΠ· модуля Data.Foldable ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ любой Ρ‚ΠΈΠΏ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ²Π΅Ρ€Π½ΡƒΡ‚ΡŒ, – Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ списки! Как ΠΈ оТидалось, ΠΎΠ±Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ foldr Π΄Π΅Π»Π°ΡŽΡ‚ со списками ΠΎΠ΄Π½ΠΎ ΠΈ Ρ‚ΠΎ ΠΆΠ΅:

ghci> foldr (*) 1 [1,2,3]

6

ghci> F.foldr (*) 1 [1,2,3]

6

Π”Ρ€ΡƒΠ³ΠΎΠΉ структурой Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰Π΅ΠΉ свёртку, являСтся Maybe, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΡ‹ всС Π·Π½Π°Π΅ΠΌ ΠΈ любим!

ghci> F.foldl (+) 2 (Just 9)

11

ghci> F.foldr (||) False (Just True)

True

Но сворачиваниС значСния Maybe Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ-Ρ‚ΠΎ интСрСсно. Оно дСйствуСт просто ΠΊΠ°ΠΊ список с ΠΎΠ΄Π½ΠΈΠΌ элСмСнтом, Ссли это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Just, ΠΈ ΠΊΠ°ΠΊ пустой список, Ссли это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Nothing. Π”Π°Π²Π°ΠΉΡ‚Π΅ рассмотрим Ρ‡ΡƒΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ ΡΠ»ΠΎΠΆΠ½ΡƒΡŽ структуру Π΄Π°Π½Π½Ρ‹Ρ….

ΠŸΠΎΠΌΠ½ΠΈΡ‚Π΅ Π΄Ρ€Π΅Π²ΠΎΠ²ΠΈΠ΄Π½ΡƒΡŽ структуру Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· Π³Π»Π°Π²Ρ‹ 7? ΠœΡ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π΅Ρ‘ Ρ‚Π°ΠΊ:

data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show)

Π’Ρ‹ ΡƒΠ·Π½Π°Π»ΠΈ, Ρ‡Ρ‚ΠΎ Π΄Π΅Ρ€Π΅Π²ΠΎ – это Π»ΠΈΠ±ΠΎ пустоС Π΄Π΅Ρ€Π΅Π²ΠΎ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½Π΅ содСрТит Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, Π»ΠΈΠ±ΠΎ ΡƒΠ·Π΅Π», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит ΠΎΠ΄Π½ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π΄Π²Π° Π΄Ρ€ΡƒΠ³ΠΈΡ… Π΄Π΅Ρ€Π΅Π²Π°. ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ ΠΌΡ‹ Π΅Π³ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ, ΠΌΡ‹ сдСлали для Π½Π΅Π³ΠΎ экзСмпляр класса Functor, ΠΈ это Π΄Π°Π»ΠΎ Π½Π°ΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ Π΅Π³ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ fmap. Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ для Π½Π΅Π³ΠΎ экзСмпляр класса Foldable, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρƒ нас появилась Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Π΅Π³ΠΎ свёртку.

Один ΠΈΠ· способов ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ для конструктора Ρ‚ΠΈΠΏΠ° экзСмпляр класса Foldable состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ просто Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ для Π½Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ foldr. Но Π΄Ρ€ΡƒΠ³ΠΎΠΉ, часто Π±ΠΎΠ»Π΅Π΅ простой способ состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ foldMap, которая Ρ‚Π°ΠΊΠΆΠ΅ являСтся ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ класса Ρ‚ΠΈΠΏΠΎΠ² Foldable. Π£ Π½Π΅Ρ‘ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ‚ΠΈΠΏ:

foldMap :: (Monoid m, Foldable t) => (a –> m) –> t a –> m

Π•Ρ‘ ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ являСтся функция, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π°Ρ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит наша сворачиваСмая структура (ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π΅Π½ здСсь ΠΊΠ°ΠΊ a), ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰Π°Ρ ΠΌΠΎΠ½ΠΎΠΈΠ΄Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π’Ρ‚ΠΎΡ€ΠΎΠΉ Π΅Ρ‘ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ – сворачиваСмая структура, содСрТащая значСния Ρ‚ΠΈΠΏΠ° a. Π­Ρ‚Π° функция ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ структуру с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π·Π°Π΄Π°Π½Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, производя ΡΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌΡƒΡŽ структуру, которая содСрТит ΠΌΠΎΠ½ΠΎΠΈΠ΄Π½Ρ‹Π΅ значСния. Π—Π°Ρ‚Π΅ΠΌ, объСдиняя эти ΠΌΠΎΠ½ΠΎΠΈΠ΄Π½Ρ‹Π΅ значСния с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ mappend, ΠΎΠ½Π° сводит ΠΈΡ… всС Π² ΠΎΠ΄Π½ΠΎ ΠΌΠΎΠ½ΠΎΠΈΠ΄Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. На Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ функция ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ нСсколько странной, Π½ΠΎ Π²Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π΅Ρ‘ ΠΎΡ‡Π΅Π½ΡŒ просто Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ. И Ρ‚Π°ΠΊΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ достаточно, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ для нашСго Ρ‚ΠΈΠΏΠ° экзСмпляр класса Foldable! ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ссли ΠΌΡ‹ просто Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ foldMap для ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ Ρ‚ΠΈΠΏΠ°, Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ foldr ΠΈ foldl для этого Ρ‚ΠΈΠΏΠ° Π΄Π°Ρ€ΠΎΠΌ!

Π’ΠΎΡ‚ ΠΊΠ°ΠΊ ΠΌΡ‹ Π΄Π΅Π»Π°Π΅ΠΌ экзСмпляр класса Foldable для Ρ‚ΠΈΠΏΠ°:

instance F.Foldable Tree where

   foldMap f EmptyTree = mempty

   foldMap f (Node x l r) = F.foldMap f l `mappend`

                         f x           `mappend`

                         F.foldMap f r

Если Π½Π°ΠΌ прСдоставлСна функция, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ элСмСнт нашСго Π΄Π΅Ρ€Π΅Π²Π° ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΌΠΎΠ½ΠΎΠΈΠ΄Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ρ‚ΠΎ ΠΊΠ°ΠΊ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ нашС Ρ†Π΅Π»ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ Π² ΠΎΠ΄Π½ΠΎ ΠΌΠΎΠ½ΠΎΠΈΠ΄Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅? Когда ΠΌΡ‹ использовали Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ fmap с нашим Π΄Π΅Ρ€Π΅Π²ΠΎΠΌ, ΠΌΡ‹ примСняли Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, отобраТая с Π΅Ρ‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΡƒΠ·Π΅Π», Π° Π·Π°Ρ‚Π΅ΠΌ рСкурсивно ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π»ΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π»Π΅Π²ΠΎΠ΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€Π΅Π²ΠΎ, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€Π°Π²ΠΎΠ΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€Π΅Π²ΠΎ. Π—Π΄Π΅ΡΡŒ наша Π·Π°Π΄Π°Ρ‡Π° состоит Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π½ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ ΠΈ Π² соСдинСнии Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ ΠΌΠΎΠ½ΠΎΠΈΠ΄Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ с использованиСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ mappend. Π‘Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ рассматриваСм случай с пустым Π΄Π΅Ρ€Π΅Π²ΠΎΠΌ – ΠΏΠ΅Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΈ ΠΎΠ΄ΠΈΠ½ΠΎΠΊΠΈΠΌ Π΄Π΅Ρ€Π΅Π²Ρ†Π΅ΠΌ, Ρƒ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΈΠ»ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€Π΅Π²ΡŒΠ΅Π². Оно Π½Π΅ содСрТит Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ нашСй Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΡΠΎΠ·Π΄Π°ΡŽΡ‰Π΅ΠΉ ΠΌΠΎΠ½ΠΎΠΈΠ΄, поэтому ΠΌΡ‹ просто Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ссли нашС Π΄Π΅Ρ€Π΅Π²ΠΎ пусто, Ρ‚ΠΎ ΠΌΠΎΠ½ΠΎΠΈΠ΄Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΎΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‰Π΅Π½ΠΎ, Ρ€Π°Π²Π½ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ mempty.