newtype State s a = State { runState :: s β> (a, s) }
Π’ΠΈΠΏ State s a β ΡΡΠΎ ΡΠΈΠΏ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΌΠ°Π½ΠΈΠΏΡΠ»ΠΈΡΡΠ΅Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ ΡΠΈΠΏΠ° s ΠΈ ΠΈΠΌΠ΅Π΅Ρ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΡΠΈΠΏΠ° a.
ΠΠ°ΠΊ ΠΈ ΠΌΠΎΠ΄ΡΠ»Ρ Control.Monad.Writer, ΠΌΠΎΠ΄ΡΠ»Ρ Control.Monad.State Π½Π΅ ΡΠΊΡΠΏΠΎΡΡΠΈΡΡΠ΅Ρ ΡΠ²ΠΎΠΉ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ. ΠΡΠ»ΠΈ Π²Ρ Ρ ΠΎΡΠΈΡΠ΅ Π²Π·ΡΡΡ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ ΠΈ ΠΎΠ±Π΅ΡΠ½ΡΡΡ Π΅Π³ΠΎ Π² newtype State, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΡΡΠ½ΠΊΡΠΈΡ state, ΠΊΠΎΡΠΎΡΠ°Ρ Π΄Π΅Π»Π°Π΅Ρ ΡΠΎ ΠΆΠ΅ ΡΠ°ΠΌΠΎΠ΅, ΡΡΠΎ Π΄Π΅Π»Π°Π» Π±Ρ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ State.
Π’Π΅ΠΏΠ΅ΡΡ, ΠΊΠΎΠ³Π΄Π° Π²Ρ ΡΠ²ΠΈΠ΄Π΅Π»ΠΈ, Π² ΡΡΠΌ Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ ΡΡΡΡ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠΉ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ ΠΈ ΠΊΠ°ΠΊ ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π°ΠΆΠ΅ Π²ΠΎΡΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡ Π² Π²ΠΈΠ΄Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Ρ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°ΠΌΠΈ, Π΄Π°Π²Π°ΠΉΡΠ΅ ΡΠ°ΡΡΠΌΠΎΡΡΠΈΠΌ ΠΈΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ ΠΊΠ»Π°ΡΡΠ° Monad:
instance Monad (State s) where
return x = State $ \s β> (x, s)
(State h) >>= f = State $ \s β> let (a, newState) = h s
(State g) = f a
in g newState
ΠΠ°ΡΠ° ΡΠ΅Π»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΈ return ΡΠΎΡΡΠΎΠΈΡ Π² ΡΠΎΠΌ, ΡΡΠΎΠ±Ρ Π²Π·ΡΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΈ ΡΠΎΠ·Π΄Π°ΡΡ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π²ΡΠ΅Π³Π΄Π° ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΡΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΠ²ΠΎΠ΅Π³ΠΎ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°. ΠΠΎΡΡΠΎΠΌΡ ΠΌΡ ΠΏΡΠΎΡΡΠΎ ΡΠΎΠ·Π΄Π°ΡΠΌ Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΡΡ ΡΡΠ½ΠΊΡΠΈΡ \s β> (x, s). ΠΡ Π²ΡΠ΅Π³Π΄Π° ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅ΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ x Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ° Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ, Π° ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΎΡΡΠ°ΡΡΡΡ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½ΡΠΌ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΡΠ½ΠΊΡΠΈΡ return Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΠΎΠΌΠ΅ΡΠ°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π² ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ. ΠΠΎΡΠΎΠΌΡ ΡΡΠ½ΠΊΡΠΈΡ return ΡΠΎΠ·Π΄Π°ΡΡ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°, Π° ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΡΠΎΡ ΡΠ°Π½ΡΠ΅Ρ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½ΡΠΌ.
Π ΡΡΠΎ Π½Π°ΡΡΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ >>=? ΠΡ ΡΡΠΎ ΠΆ, ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠΌ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ ΡΡΠ½ΠΊΡΠΈΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ >>= Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ, Π²Π΅ΡΠ½ΠΎ? ΠΠΎΡΡΠΎΠΌΡ ΠΌΡ Π½Π°ΡΠΈΠ½Π°Π΅ΠΌ Ρ ΠΎΠ±ΡΡΡΠΊΠΈ newtype State, Π° Π·Π°ΡΠ΅ΠΌ Π²ΡΠ·ΡΠ²Π°Π΅ΠΌ Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΡΡ ΡΡΠ½ΠΊΡΠΈΡ. ΠΡΠ° Π°Π½ΠΎΠ½ΠΈΠΌΠ½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ Π±ΡΠ΄Π΅Ρ Π½Π°ΡΠΈΠΌ Π½ΠΎΠ²ΡΠΌ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ΠΌ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ. ΠΠΎ ΡΡΠΎ ΠΆΠ΅ Π² Π½Π΅ΠΉ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ? ΠΠ°ΠΌ ΠΊΠ°ΠΊΠΈΠΌ-ΡΠΎ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ Π½ΡΠΆΠ½ΠΎ ΠΈΠ·Π²Π»Π΅ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ° ΠΈΠ· ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ. ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΏΡΡΠΌΠΎ ΡΠ΅ΠΉΡΠ°Ρ ΠΌΡ Π½Π°Ρ ΠΎΠ΄ΠΈΠΌΡΡ Π² Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠΈ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ, ΡΠΎ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ h Π½Π°ΡΠ΅ ΡΠ΅ΠΊΡΡΠ΅Π΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ s, ΡΡΠΎ Π² ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ Π΄Π°ΡΡ ΠΏΠ°ΡΡ ΠΈΠ· ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ° ΠΈ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ: (a, newState).
ΠΠΎ ΡΠΈΡ ΠΏΠΎΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π·, ΠΊΠΎΠ³Π΄Π° ΠΌΡ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²ΡΠ²Π°Π»ΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ >>=, ΡΡΠ°Π·Ρ ΠΆΠ΅ ΠΏΠΎΡΠ»Π΅ ΠΈΠ·Π²Π»Π΅ΡΠ΅Π½ΠΈΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ° ΠΈΠ· ΠΌΠΎΠ½Π°Π΄ΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΌΡ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ»ΠΈ ΠΊ Π½Π΅ΠΌΡ ΡΡΠ½ΠΊΡΠΈΡ f, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π½ΠΎΠ²ΠΎΠ΅ ΠΌΠΎΠ½Π°Π΄ΠΈΡΠ΅ΡΠΊΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅. Π ΡΠ»ΡΡΠ°Π΅ Ρ ΠΌΠΎΠ½Π°Π΄ΠΎΠΉ Writer ΠΏΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΡΡΠΎ ΡΠ΄Π΅Π»Π°Π½ΠΎ ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΎ Π½ΠΎΠ²ΠΎΠ΅ ΠΌΠΎΠ½Π°Π΄ΠΈΡΠ΅ΡΠΊΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, Π½Π°ΠΌ ΠΏΠΎ-ΠΏΡΠ΅ΠΆΠ½Π΅ΠΌΡ Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠ·Π°Π±ΠΎΡΠΈΡΡΡΡ ΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅, ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½ΠΈΠ² ΠΏΡΠ΅ΠΆΠ½Π΅Π΅ ΠΈ Π½ΠΎΠ²ΠΎΠ΅ ΠΌΠΎΠ½ΠΎΠΈΠ΄Π½ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ mappend. ΠΠ΄Π΅ΡΡ ΠΌΡ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌ Π²ΡΠ·ΠΎΠ² Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ f a ΠΈ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ Π½ΠΎΠ²ΠΎΠ΅ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ g. Π’Π΅ΠΏΠ΅ΡΡ, ΠΊΠΎΠ³Π΄Π° Ρ Π½Π°Ρ Π΅ΡΡΡ Π½ΠΎΠ²ΠΎΠ΅ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ ΠΈ Π½ΠΎΠ²ΠΎΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ (ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎΠ΅ ΠΏΠΎΠ΄ ΠΈΠΌΠ΅Π½Π΅ΠΌ newState), ΠΌΡ ΠΏΡΠΎΡΡΠΎ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ ΡΡΠΎ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ g ΠΊ newState. Π Π΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠΌ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΊΠΎΡΡΠ΅ΠΆ ΠΈΠ· ΠΎΠΊΠΎΠ½ΡΠ°ΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ° ΠΈ ΠΎΠΊΠΎΠ½ΡΠ°ΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ!
ΠΡΠ°ΠΊ, ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ >>= ΠΌΡ ΠΊΠ°ΠΊ Π±Ρ Β«ΡΠΊΠ»Π΅ΠΈΠ²Π°Π΅ΠΌΒ» Π΄ΡΡΠ³ Ρ Π΄ΡΡΠ³ΠΎΠΌ Π΄Π²Π° Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ, ΠΎΠ±Π»Π°Π΄Π°ΡΡΠΈΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ. ΠΡΠΎΡΠΎΠ΅ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ ΡΠΊΡΡΡΠΎ Π²Π½ΡΡΡΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅Π³ΠΎ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ. ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΡΠ½ΠΊΡΠΈΠΈ pop ΠΈ push ΡΠΆΠ΅ ΡΠ²Π»ΡΡΡΡΡ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡΠΌΠΈ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ, Π»Π΅Π³ΠΊΠΎ ΠΎΠ±Π΅ΡΠ½ΡΡΡ ΠΈΡ Π² ΠΎΠ±ΡΡΡΠΊΡ State:
import Control.Monad.State
pop :: State Stack Int
pop = state $ \(x:xs) β> (x, xs)
push :: Int β> State Stack ()
push a = state $ \xs β> ((), a:xs)
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΠΊΠ°ΠΊ ΠΌΡ Π·Π°Π΄Π΅ΠΉΡΡΠ²ΠΎΠ²Π°Π»ΠΈ ΡΡΠ½ΠΊΡΠΈΡ state, ΡΡΠΎΠ±Ρ ΠΎΠ±Π΅ΡΠ½ΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ Π² ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ newtype State, Π½Π΅ ΠΏΡΠΈΠ±Π΅Π³Π°Ρ ΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΠ° Π·Π½Π°ΡΠ΅Π½ΠΈΡ State Π½Π°ΠΏΡΡΠΌΡΡ.
Π€ΡΠ½ΠΊΡΠΈΡ pop β ΡΠΆΠ΅ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ, Π° ΡΡΠ½ΠΊΡΠΈΡ push ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠΈΠΏΠ° Int ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ. Π’Π΅ΠΏΠ΅ΡΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅ΡΠ΅ΠΏΠΈΡΠ°ΡΡ Π½Π°Ρ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΠΉ ΠΏΡΠΈΠΌΠ΅Ρ ΠΏΡΠΎΡΠ°Π»ΠΊΠΈΠ²Π°Π½ΠΈΡ ΡΠΈΡΠ»Π° 3 Π² ΡΡΠ΅ΠΊ ΠΈ Π²ΡΡΠ°Π»ΠΊΠΈΠ²Π°Π½ΠΈΡ Π΄Π²ΡΡ ΡΠΈΡΠ΅Π» ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
import Control.Monad.State
stackManip :: State Stack Int
stackManip = do
push 3
a <β pop
pop
ΠΠΈΠ΄ΠΈΡΠ΅, ΠΊΠ°ΠΊ ΠΌΡ Β«ΡΠΊΠ»Π΅ΠΈΠ»ΠΈΒ» ΠΏΡΠΎΡΠ°Π»ΠΊΠΈΠ²Π°Π½ΠΈΠ΅ ΠΈ Π΄Π²Π° Π²ΡΡΠ°Π»ΠΊΠΈΠ²Π°Π½ΠΈΡ Π² ΠΎΠ΄Π½ΠΎ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ? Π Π°Π·Π²ΠΎΡΠ°ΡΠΈΠ²Π°Ρ Π΅Π³ΠΎ ΠΈΠ· ΠΎΠ±ΡΡΡΠΊΠΈ newtype, ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²ΠΈΡΡ Π½Π΅ΠΊΠΎΠ΅ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅:
ghci> runState stackManip [5,8,2,1]
(5,[8,2,1])
ΠΠ°ΠΌ Π½Π΅ ΡΡΠ΅Π±ΠΎΠ²Π°Π»ΠΎΡΡ ΠΏΡΠΈΠ²ΡΠ·ΡΠ²Π°ΡΡ Π²ΡΠΎΡΠΎΠΉ Π²ΡΠ·ΠΎΠ² ΡΡΠ½ΠΊΡΠΈΠΈ pop ΠΊ ΠΎΠ±ΡΠ°Π·ΡΡ a, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΠΌΡ Π²ΠΎΠ²ΡΠ΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΠΈ ΡΡΠΎΡ ΠΎΠ±ΡΠ°Π·Π΅Ρ. ΠΠ½Π°ΡΠΈΡ, ΡΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ Π·Π°ΠΏΠΈΡΠ°ΡΡ Π²ΠΎΡ ΡΠ°ΠΊ:
stackManip :: State Stack Int
stackManip = do
push 3
pop
pop
ΠΡΠ΅Π½Ρ ΠΊΡΡΡΠΎ! ΠΠΎ ΡΡΠΎ Π΅ΡΠ»ΠΈ ΠΌΡ Ρ ΠΎΡΠΈΠΌ ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠΎ-Π½ΠΈΠ±ΡΠ΄Ρ ΠΏΠΎΡΠ»ΠΎΠΆΠ½Π΅Π΅? Π‘ΠΊΠ°ΠΆΠ΅ΠΌ, Π²ΡΡΠΎΠ»ΠΊΠ½ΡΡΡ ΠΈΠ· ΡΡΠ΅ΠΊΠ° ΠΎΠ΄Π½ΠΎ ΡΠΈΡΠ»ΠΎ, ΠΈ Π΅ΡΠ»ΠΈ ΡΡΠΎ ΡΠΈΡΠ»ΠΎ ΡΠ°Π²Π½ΠΎ 5, ΠΏΡΠΎΡΡΠΎ ΠΏΡΠΎΡΠΎΠ»ΠΊΠ½ΡΡΡ Π΅Π³ΠΎ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ Π² ΡΡΠ΅ΠΊ ΠΈ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡΡ. ΠΠΎ Π΅ΡΠ»ΠΈ ΡΠΈΡΠ»ΠΎ Π½Π΅ ΡΠ°Π²Π½ΠΎ 5, Π²ΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΏΡΠΎΡΠΎΠ»ΠΊΠ½ΡΡΡ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ 3 ΠΈ 8. ΠΠΎΡ ΠΎΠ½ ΠΊΠΎΠ΄:
stackStuff :: State Stack ()
stackStuff = do
a <β pop
if a == 5
then push 5
else do
push 3
push 8
ΠΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ ΠΏΡΠΎΡΡΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅. ΠΠ°Π²Π°ΠΉΡΠ΅ Π²ΡΠΏΠΎΠ»Π½ΠΈΠΌ ΡΡΠΎΡ ΠΊΠΎΠ΄ Ρ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΌ ΡΡΠ΅ΠΊΠΎΠΌ:
ghci> runState stackStuff [9,0,2,1,0] ((),[8,3,0,2,1,0])
ΠΡΠΏΠΎΠΌΠ½ΠΈΡΠ΅, ΡΡΠΎ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ do Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ Π² ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ ΠΌΠΎΠ½Π°Π΄ΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ, ΠΈ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΌΠΎΠ½Π°Π΄Ρ State ΠΎΠ΄Π½ΠΎ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ do ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ°ΠΊΠΆΠ΅ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ. ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΡΠ½ΠΊΡΠΈΠΈ stackManip ΠΈ stackStuff ΡΠ²Π»ΡΡΡΡΡ ΠΎΠ±ΡΡΠ½ΡΠΌΠΈ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡΠΌΠΈ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Β«ΡΠΊΠ»Π΅ΠΈΠ²Π°ΡΡΒ» ΠΈΡ Π²ΠΌΠ΅ΡΡΠ΅, ΡΡΠΎΠ±Ρ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΡ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠΈΠ΅ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ:
moreStack :: State Stack ()
moreStack = do
a <β stackManip
if a == 100
then stackStuff
else return ()
ΠΡΠ»ΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΡΡΠ½ΠΊΡΠΈΠΈ stackManip ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ ΡΡΠ΅ΠΊΠ° ΡΠ°Π²Π΅Π½ 100, ΠΌΡ Π²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ stackStuff; Π² ΠΏΡΠΎΡΠΈΠ²Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ Π΄Π΅Π»Π°Π΅ΠΌ. ΠΡΠ·ΠΎΠ² return () ΠΏΡΠΎΡΡΠΎ ΡΠΎΡ ΡΠ°Π½ΡΠ΅Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΊΠ°ΠΊ Π΅ΡΡΡ ΠΈ Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ.
ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΈ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ° ΡΠΎΡΡΠΎΡΠ½ΠΈΡ
ΠΠΎΠ΄ΡΠ»Ρ Control.Monad.State ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΠΊΠ»Π°ΡΡ ΡΠΈΠΏΠΎΠ² ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ MonadState, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΏΡΠΈΡΡΡΡΡΠ²ΡΡΡ Π΄Π²Π΅ Π²Π΅ΡΡΠΌΠ° ΠΏΠΎΠ»Π΅Π·Π½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ: get ΠΈ put. ΠΠ»Ρ ΠΌΠΎΠ½Π°Π΄Ρ State ΡΡΠ½ΠΊΡΠΈΡ get ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° Π²ΠΎΡ ΡΠ°ΠΊ:
get = state $ \s β> (s, s)
ΠΠ½Π° ΠΏΡΠΎΡΡΠΎ Π±Π΅ΡΡΡ ΡΠ΅ΠΊΡΡΠ΅Π΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΈ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ Π΅Π³ΠΎ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°.
Π€ΡΠ½ΠΊΡΠΈΡ put ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΈ ΡΠΎΠ·Π΄Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ, ΠΊΠΎΡΠΎΡΠ°Ρ Π·Π°ΠΌΠ΅Π½ΡΠ΅Ρ ΠΈΠΌ ΡΠ΅ΠΊΡΡΠ΅Π΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅:
put newState = state $ \s β> ((), newState)
ΠΠΎΡΡΠΎΠΌΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΈΡ , ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ, ΡΠ΅ΠΌΡ ΡΠ°Π²Π΅Π½ ΡΠ΅ΠΊΡΡΠΈΠΉ ΡΡΠ΅ΠΊ, Π»ΠΈΠ±ΠΎ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ Π΅Π³ΠΎ Π΄ΡΡΠ³ΠΈΠΌ ΡΡΠ΅ΠΊΠΎΠΌ β Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠ°ΠΊ:
stackyStack :: State Stack ()
stackyStack = do
stackNow <β get
if stackNow == [1,2,3]
then put [8,3,1]
else put [9,2,1]
Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ get ΠΈ put, ΡΡΠΎΠ±Ρ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ pop ΠΈ push. ΠΠΎΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ pop:
pop :: State Stack Int
pop = do
(x:xs) <β get
put xs
return x
ΠΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ get, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π²Π΅ΡΡ ΡΡΠ΅ΠΊ, Π° Π·Π°ΡΠ΅ΠΌ β ΡΡΠ½ΠΊΡΠΈΡ put, ΡΡΠΎΠ±Ρ Π½ΠΎΠ²ΡΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ Π±ΡΠ»ΠΈ Π²ΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π·Π° ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ Π²Π΅ΡΡ Π½Π΅Π³ΠΎ. ΠΠΎΡΠ»Π΅ ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ±Π΅Π³Π°Π΅ΠΌ ΠΊ ΡΡΠ½ΠΊΡΠΈΠΈ return, ΡΡΠΎΠ±Ρ ΠΏΡΠ΅Π΄ΡΡΠ°Π²ΠΈΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ x Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°.
ΠΠΎΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ push, ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΉ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ get ΠΈ put:
push :: Int β> State Stack ()
push x = do
xs <β get
put (x:xs)
ΠΡ ΠΏΡΠΎΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ get, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠ΅ΠΊΡΡΠ΅Π΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅, ΠΈ ΡΡΠ½ΠΊΡΠΈΡ put, ΡΡΠΎΠ±Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ Π² ΡΠ°ΠΊΠΎΠ΅ ΠΆΠ΅, ΠΊΠ°ΠΊ Π½Π°Ρ ΡΡΠ΅ΠΊ Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠΌ x Π½Π° Π²Π΅ΡΡΠΈΠ½Π΅.
Π‘ΡΠΎΠΈΡ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ, ΠΊΠ°ΠΊΠΈΠΌ Π±ΡΠ» Π±Ρ ΡΠΈΠΏ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ >>=, Π΅ΡΠ»ΠΈ Π±Ρ ΠΎΠ½Π° ΡΠ°Π±ΠΎΡΠ°Π»Π° ΡΠΎΠ»ΡΠΊΠΎ ΡΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡΠΌΠΈ ΠΌΠΎΠ½Π°Π΄Ρ State:
(>>=) :: State s a β> (a β> State s b) β> State s b
ΠΠΈΠ΄ΠΈΡΠ΅, ΠΊΠ°ΠΊ ΡΠΈΠΏ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ s ΠΎΡΡΠ°ΡΡΡΡ ΡΠ΅ΠΌ ΠΆΠ΅, Π½ΠΎ ΡΠΈΠΏ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ° ΠΌΠΎΠΆΠ΅Ρ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡΡΡ Ρ a Π½Π° b? ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Β«ΡΠΊΠ»Π΅ΠΈΠ²Π°ΡΡΒ» Π²ΠΌΠ΅ΡΡΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠΉ Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ, ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ ΠΊΠΎΡΠΎΡΡΡ ΠΈΠΌΠ΅ΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΡΠΈΠΏΡ, Π½ΠΎ ΡΠΈΠΏ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡΡΠ°Π²Π°ΡΡΡΡ ΡΠ΅ΠΌ ΠΆΠ΅. ΠΠΎΡΠ΅ΠΌΡ ΠΆΠ΅ ΡΠ°ΠΊ?.. ΠΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π»Ρ ΡΠΈΠΏΠ° Maybe ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ >>= ΠΈΠΌΠ΅Π΅Ρ ΡΠ°ΠΊΠΎΠΉ ΡΠΈΠΏ:
(>>=) :: Maybe a β> (a β> Maybe b) β> Maybe b
ΠΠΎΠ³ΠΈΡΠ½ΠΎ, ΡΡΠΎ ΡΠ°ΠΌΠ° ΠΌΠΎΠ½Π°Π΄Π° Maybe Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΡΡΡ. ΠΠ΅ ΠΈΠΌΠ΅Π»ΠΎ Π±Ρ ΡΠΌΡΡΠ»Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ >>= ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²ΡΠΌΡ ΡΠ°Π·Π½ΡΠΌΠΈ ΠΌΠΎΠ½Π°Π΄Π°ΠΌΠΈ. ΠΠ»Ρ ΠΌΠΎΠ½Π°Π΄Ρ State ΠΌΠΎΠ½Π°Π΄ΠΎΠΉ Π½Π° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ State s, ΡΠ°ΠΊ ΡΡΠΎ Π΅ΡΠ»ΠΈ Π±Ρ ΡΡΠΎΡ ΡΠΈΠΏ s Π±ΡΠ» ΡΠ°Π·Π»ΠΈΡΠ½ΡΠΌ, ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΠΈ Π±Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ >>= ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²ΡΠΌΡ ΡΠ°Π·Π½ΡΠΌΠΈ ΠΌΠΎΠ½Π°Π΄Π°ΠΌΠΈ.