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

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

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

Π‘Π»ΡƒΡ‡Π°ΠΉΠ½ΠΎΡΡ‚ΡŒ ΠΈ ΠΌΠΎΠ½Π°Π΄Π° State

Π’ Π½Π°Ρ‡Π°Π»Π΅ этого Ρ€Π°Π·Π΄Π΅Π»Π° ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΈ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ гСнСрация случайных чисСл ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ½ΠΎΠ³Π΄Π° Π±Ρ‹Ρ‚ΡŒ Π½Π΅ΡƒΠΊΠ»ΡŽΠΆΠ΅ΠΉ. КаТдая функция, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π°Ρ ΡΠ»ΡƒΡ‡Π°ΠΉΠ½ΠΎΡΡ‚ΡŒ, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ случайноС число вмСстС с Π½ΠΎΠ²Ρ‹ΠΌ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π·Π°Ρ‚Π΅ΠΌ Π±Ρ‹Ρ‚ΡŒ использован вмСсто ΠΏΡ€Π΅ΠΆΠ½Π΅Π³ΠΎ, Ссли Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Ρ‰Ρ‘ ΠΎΠ΄Π½ΠΎ случайноС число. Монада State Π½Π°ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ эти дСйствия.

Ѐункция random ΠΈΠ· модуля System.Random ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ‚ΠΈΠΏ:

random :: (RandomGen g, Random a) => g –> (a, g)

Π­Ρ‚ΠΎ Π·Π½Π°Ρ‡ΠΈΡ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° Π±Π΅Ρ€Ρ‘Ρ‚ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ случайных чисСл ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ случайноС число вмСстС с Π½ΠΎΠ²Ρ‹ΠΌ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ. Нам Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ это вычислСниС с состояниСм, поэтому ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±Π΅Ρ€Π½ΡƒΡ‚ΡŒ Π΅Π³ΠΎ Π² конструктор newtype State ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ state, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² качСствС монадичСского значСния, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° состояния ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π»Π°ΡΡŒ Π·Π° нас:

import System.Random

import Control.Monad.State


randomSt :: (RandomGen g, Random a) => State g a

randomSt = state random

ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ, Ссли ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΠΎΠ΄Π±Ρ€ΠΎΡΠΈΡ‚ΡŒ Ρ‚Ρ€ΠΈ ΠΌΠΎΠ½Π΅Ρ‚Ρ‹ (True – это Β«Ρ€Π΅ΡˆΠΊΠ°Β», Π° False – Β«ΠΎΡ€Ρ‘Π»Β»), Ρ‚ΠΎ просто Π΄Π΅Π»Π°Π΅ΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅:

import System.Random

import Control.Monad.State


threeCoins :: State StdGen (Bool, Bool, Bool)

threeCoins = do

   a <– randomSt

   b <– randomSt

   c <– randomSt

   return (a, b, c)

Ѐункция threeCoins – это Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ вычислСниС с состояниСм, ΠΈ послС получСния исходного Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° случайных чисСл ΠΎΠ½Π° ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‘Ρ‚ этот Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π² ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ randomSt, которая ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ число ΠΈ Π½ΠΎΠ²Ρ‹ΠΉ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹ΠΉ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΈ Ρ‚. Π΄. ΠœΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ return (a, b, c), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ (a, b, c) ΠΊΠ°ΠΊ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π½Π΅ измСняя самый послСдний Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€. Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ:

ghci> runState threeCoins (mkStdGen 33)

((True,False,True),680029187 2103410263)

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ всСго, Ρ‡Ρ‚ΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ сохранСния Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ состояния Π² ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΊΠ°Ρ… ΠΌΠ΅ΠΆΠ΄Ρƒ шагами, Π² самом Π΄Π΅Π»Π΅ стало Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ мСньшС Ρ…Π»ΠΎΠΏΠΎΡ‚!

Π‘Π²Π΅Ρ‚ ΠΌΠΎΠΉ, Error, скаТи, Π΄Π° всю ΠΏΡ€Π°Π²Π΄Ρƒ Π΄ΠΎΠ»ΠΎΠΆΠΈ

К этому Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π²Ρ‹ Π·Π½Π°Π΅Ρ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠ½Π°Π΄Π° Maybe ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊ значСниям контСкст Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ Π½Π΅ΡƒΠ΄Π°Ρ‡ΠΈ. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Just <Π½Π΅Ρ‡Ρ‚ΠΎ> Π»ΠΈΠ±ΠΎ Nothing. Как Π±Ρ‹ это Π½ΠΈ Π±Ρ‹Π»ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, всё, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ извСстно, ΠΊΠΎΠ³Π΄Π° Ρƒ нас Π΅ΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Nothing, – это ΡΠΎΡΡ‚ΠΎΡΠ²ΡˆΠΈΠΉΡΡ Ρ„Π°ΠΊΡ‚ Π½Π΅ΠΊΠΎΠ΅ΠΉ Π½Π΅ΡƒΠ΄Π°Ρ‡ΠΈ: Ρ‚ΡƒΠ΄Π° Π½Π΅ Π²Ρ‚ΠΈΡΠ½ΡƒΡ‚ΡŒ большС ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ, ΡΠΎΠΎΠ±Ρ‰Π°ΡŽΡ‰Π΅ΠΉ Π½Π°ΠΌ, Ρ‡Ρ‚ΠΎ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ.

И Ρ‚ΠΈΠΏ Either e a позволяСт Π½Π°ΠΌ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ контСкст Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ Π½Π΅ΡƒΠ΄Π°Ρ‡ΠΈ Π² наши значСния. Π‘ Π΅Π³ΠΎ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ‚ΠΎΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠΊΡ€Π΅ΠΏΠ»ΡΡ‚ΡŒ значСния ΠΊ Π½Π΅ΡƒΠ΄Π°Ρ‡Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΈ ΠΌΠΎΠ³Π»ΠΈ ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΈΠΌΠ΅Π½Π½ΠΎ пошло Π½Π΅ Ρ‚Π°ΠΊ, Π»ΠΈΠ±ΠΎ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΡƒΡŽ ΠΏΠΎΠ»Π΅Π·Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ошибки. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Either e a ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Right (ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‚ ΠΈ успСх) Π»ΠΈΠ±ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Left (Π½Π΅ΡƒΠ΄Π°Ρ‡Π°). Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

ghci> :t Right 4

Right 4 :: (Num t) => Either a t

ghci> :t Left "ошибка Π½Π΅Ρ…Π²Π°Ρ‚ΠΊΠΈ сыра"

Left "ошибка Π½Π΅Ρ…Π²Π°Ρ‚ΠΊΠΈ сыра" :: Either [Char] b

Π­Ρ‚ΠΎ практичСски всСго лишь ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½Π½Ρ‹ΠΉ Ρ‚ΠΈΠΏ Maybe, поэтому ΠΈΠΌΠ΅Π΅Ρ‚ смысл, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ Π±Ρ‹Π» ΠΌΠΎΠ½Π°Π΄ΠΎΠΉ. Он ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒΡΡ ΠΈ ΠΊΠ°ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ с Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π½Ρ‹ΠΌ контСкстом Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ Π½Π΅ΡƒΠ΄Π°Ρ‡ΠΈ, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ошибки Ρ‚Π°ΠΊΠΆΠ΅ имССтся ΠΏΡ€ΠΈΠΊΡ€Π΅ΠΏΠ»Ρ‘Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.

Π•Π³ΠΎ экзСмпляр класса Monad ΠΏΠΎΡ…ΠΎΠΆ Π½Π° экзСмпляр для Ρ‚ΠΈΠΏΠ° Maybe ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ Π² ΠΌΠΎΠ΄ΡƒΠ»Π΅ Control.Monad.Error[15]:

instance (Error e) => Monad (Either e) where

   return x = Right x

   Right x >>= f = f x

   Left err >>= f = Left err

   fail msg = Left (strMsg msg)

Ѐункция return, ΠΊΠ°ΠΊ ΠΈ всСгда, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π΅Π³ΠΎ Π² ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ контСкст ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Она ΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚ нашС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² конструктор Right, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π΅Π³ΠΎ для прСдставлСния ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹Ρ… вычислСний, Π³Π΄Π΅ присутствуСт Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚. Π­Ρ‚ΠΎ ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΡ…ΠΎΠΆΠ΅ Π½Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° return для Ρ‚ΠΈΠΏΠ° Maybe.

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ >>= провСряСт Π΄Π²Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… случая: Left ΠΈ Right. Π’ случаС Right ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π½Π΅Π³ΠΎ примСняСтся функция f, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ ΡΠ»ΡƒΡ‡Π°ΡŽ Just, Π³Π΄Π΅ ΠΊ Π΅Π³ΠΎ содСрТимому просто примСняСтся функция. Π’ случаС ошибки сохраняСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Left вмСстС с Π΅Π³ΠΎ содСрТимым, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ описываСт Π½Π΅ΡƒΠ΄Π°Ρ‡Ρƒ.

ЭкзСмпляр класса Monad для Ρ‚ΠΈΠΏΠ° Either e ΠΈΠΌΠ΅Π΅Ρ‚ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠ΅. Π’ΠΈΠΏ значСния, содСрТащСгося Π² Left, – Ρ‚ΠΎΡ‚, Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Π°Π½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ Ρ‚ΠΈΠΏΠ° e, – Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ экзСмпляром класса Error. Класс Error ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для Ρ‚ΠΈΠΏΠΎΠ², значСния ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΌΠΎΠ³ΡƒΡ‚ Π΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ сообщСния ΠΎΠ± ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ…. Он опрСдСляСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ strMsg, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ Π² Π²ΠΈΠ΄Π΅ строки ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π₯ΠΎΡ€ΠΎΡˆΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ экзСмпляра Error – Ρ‚ΠΈΠΏ String! Π’ случаС со String функция strMsg просто Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ строку, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΎΠ½Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»Π°:

ghci> :t strMsg

strMsg :: (Error a) => String –> a

ghci> strMsg "Π‘ΡƒΠΌ!" :: String

"Π‘ΡƒΠΌ!"

Но ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΡ€ΠΈ использовании Ρ‚ΠΈΠΏΠ° Either для описания ошибки ΠΌΡ‹ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ задСйствуСм Ρ‚ΠΈΠΏ String, Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΎΠ± этом сильно Π±Π΅ΡΠΏΠΎΠΊΠΎΠΈΡ‚ΡŒΡΡ. Когда сопоставлСниС с ΠΎΠ±Ρ€Π°Π·Ρ†ΠΎΠΌ Ρ‚Π΅Ρ€ΠΏΠΈΡ‚ Π½Π΅ΡƒΠ΄Π°Ρ‡Ρƒ Π² Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ do, Ρ‚ΠΎ для оповСщСния ΠΎΠ± этой Π½Π΅ΡƒΠ΄Π°Ρ‡Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Left.

Π’ΠΎΡ‚ нСсколько практичСских ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ²:

ghci> Left "Π‘ΡƒΠΌ" >>= \x –>return (x+1)

Left "Π‘ΡƒΠΌ"

ghci> Left "Π‘ΡƒΠΌ " >>= \x –> Left "Π½Π΅Ρ‚ ΠΏΡƒΡ‚ΠΈ!"

Left "Π‘ΡƒΠΌ "

ghci> Right 100 >>= \x –> Left "Π½Π΅Ρ‚ ΠΏΡƒΡ‚ΠΈ!"

Left "Π½Π΅Ρ‚ ΠΏΡƒΡ‚ΠΈ!"

Когда ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ >>=, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Left, функция игнорируСтся ΠΈ возвращаСтся ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Left. Когда ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‘ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Right, функция примСняСтся ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ находится Π²Π½ΡƒΡ‚Ρ€ΠΈ, Π½ΠΎ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС эта функция всё Ρ€Π°Π²Π½ΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π»Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Left!

ИспользованиС ΠΌΠΎΠ½Π°Π΄Ρ‹ Error ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΡ…ΠΎΠΆΠ΅ Π½Π° использованиС ΠΌΠΎΠ½Π°Π΄Ρ‹ Maybe.

ΠŸΠ Π˜ΠœΠ•Π§ΠΠΠ˜Π•. Π’ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ Π³Π»Π°Π²Π΅ ΠΌΡ‹ использовали монадичСскиС аспСкты Ρ‚ΠΈΠΏΠ° Maybe для симуляции призСмлСния ΠΏΡ‚ΠΈΡ† Π½Π° балансировочный ΡˆΠ΅ΡΡ‚ ΠΊΠ°Π½Π°Ρ‚ΠΎΡ…ΠΎΠ΄Ρ†Π°. Π’ качСствС упраТнСния Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΊΠΎΠ΄ с использованиСм ΠΌΠΎΠ½Π°Π΄Ρ‹ Error, Ρ‡Ρ‚ΠΎΠ±Ρ‹, ΠΊΠΎΠ³Π΄Π° ΠΊΠ°Π½Π°Ρ‚ΠΎΡ…ΠΎΠ΄Π΅Ρ† ΠΏΠΎΡΠΊΠ°Π»ΡŒΠ·Ρ‹Π²Π°Π»ΡΡ ΠΈ ΠΏΠ°Π΄Π°Π», Π²Ρ‹ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΈ, сколько ΠΏΡ‚ΠΈΡ† Π±Ρ‹Π»ΠΎ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΉ сторонС ΡˆΠ΅ΡΡ‚Π° Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ падСния.

НСкоторыС ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Π΅ монадичСскиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ ΠΈΠ·ΡƒΡ‡ΠΈΠΌ нСсколько Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ с монадичСскими значСниями Π»ΠΈΠ±ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ монадичСскиС значСния Π² качСствС своих Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² (ΠΈΠ»ΠΈ ΠΈ Ρ‚ΠΎ, ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ΅!). Π’Π°ΠΊΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ монадичСскими. Π’ Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ· Π½ΠΈΡ… Π±ΡƒΠ΄ΡƒΡ‚ для вас ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π½ΠΎΠ²Ρ‹ΠΌΠΈ, Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ монадичСскими Π°Π½Π°Π»ΠΎΠ³Π°ΠΌΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ Π²Ρ‹ ΡƒΠΆΠ΅ Π·Π½Π°ΠΊΠΎΠΌΡ‹ – Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, filter ΠΈ foldl. НиТС ΠΌΡ‹ рассмотрим Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ liftM, join, filterM ΠΈ foldM.


liftM и компания

Когда ΠΌΡ‹ Π½Π°Ρ‡Π°Π»ΠΈ своё ΠΏΡƒΡ‚Π΅ΡˆΠ΅ΡΡ‚Π²ΠΈΠ΅ Π½Π° Π²Π΅Ρ€Ρ…ΡƒΡˆΠΊΡƒ Π“ΠΎΡ€Ρ‹ Монад, ΠΌΡ‹ сначала посмотрСли Π½Π° Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Ρ‹, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹Π΅ для сущностСй, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ. Π—Π°Ρ‚Π΅ΠΌ рассмотрСли ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Ρ‹ – Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π½Π°ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ нСсколькими Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ значСниями, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π±Ρ€Π°Ρ‚ΡŒ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ контСкст ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. НаконСц, ΠΌΡ‹ Π²Π²Π΅Π»ΠΈ ΠΌΠΎΠ½Π°Π΄Ρ‹ ΠΊΠ°ΠΊ ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½Π½Ρ‹Π΅ Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ‚Π΅ΠΌ ΠΈΠ»ΠΈ ΠΈΠ½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ эти значСния с контСкстом Π² ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

Π˜Ρ‚Π°ΠΊ, каТдая ΠΌΠΎΠ½Π°Π΄Π° – это Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€, Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€ – это Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€. Класс Ρ‚ΠΈΠΏΠΎΠ² Applicative ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠ΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ класса, Π²Π²ΠΈΠ΄Ρƒ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ наш Ρ‚ΠΈΠΏ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ экзСмпляр класса Functor, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ ΠΌΡ‹ смоТСм ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ для Π½Π΅Π³ΠΎ экзСмпляр класса Applicative. Класс Monad Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ‚ΠΎ ΠΆΠ΅ самоС ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ для класса Applicative, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ каТдая ΠΌΠΎΠ½Π°Π΄Π° являСтся Π°ΠΏΠΏΠ»ΠΈΠΊΠ°Ρ‚ΠΈΠ²Π½Ρ‹ΠΌ Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€ΠΎΠΌ – ΠΎΠ΄Π½Π°ΠΊΠΎ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ класс Ρ‚ΠΈΠΏΠΎΠ² Monad Π±Ρ‹Π» Π²Π²Π΅Π΄Ρ‘Π½ Π² язык Haskell Π·Π°Π΄ΠΎΠ»Π³ΠΎ Π΄ΠΎ класса Applicative.

Но хотя каТдая ΠΌΠΎΠ½Π°Π΄Π° – Ρ„ΡƒΠ½ΠΊΡ‚ΠΎΡ€, Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Ρƒ Π½Π΅Ρ‘ Π΅ΡΡ‚ΡŒ экзСмпляр для класса Functor, Π² силу наличия Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ liftM. Ѐункция liftM Π±Π΅Ρ€Ρ‘Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈ монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ монадичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π­Ρ‚ΠΎ ΠΏΠΎΡ‡Ρ‚ΠΈ ΠΎΠ΄Π½ΠΎ ΠΈ Ρ‚ΠΎ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ ΠΈ функция fmap! Π’ΠΎΡ‚ Ρ‚ΠΈΠΏ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ liftM:

liftM :: (Monad m) => (a –> b) –> m a –> m b

Π‘Ρ€Π°Π²Π½ΠΈΡ‚Π΅ с Ρ‚ΠΈΠΏΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fmap:

fmap :: (Functor f) => (a –> b) –> f a –> f b

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