рд╣рд╛рд╕реНрдХреЗрд▓ рдкрд░ 33 рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рдЦрд░реЛрдВрдЪ рд╕реЗ рд╕рд╣рдХрд╛рд░реА рдзрд╛рдЧреЗ

рд╣рд╛рд╕реНрдХреЗрд▓ рдЕрдкрдиреЗ рдЖрдк рдХреЛ рд╕рдмрд╕реЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рднрд╛рд╖рд╛рдУрдВ рд╕реЗ рдЕрд▓рдЧ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдореЗрдВ рдЧрдгрд┐рдд рдФрд░ рдХрдВрдкреНрдпреВрдЯрд░ рд╡рд┐рдЬреНрдЮрд╛рди рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдЧрд╣рд░реА рд╕рд╛рдВрд╕реНрдХреГрддрд┐рдХ рдЬрдбрд╝реЗрдВ рд╣реИрдВ, рдЬреЛ рдПрдХ рднреНрд░рд╛рдордХ рдзрд╛рд░рдгрд╛ рджреЗрддреА рд╣реИрдВ рдХрд┐ рд╣рд╕реНрдХреЗрд▓ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЦрд░рд╛рдм рд░реВрдк рд╕реЗ рдЕрдиреБрдХреВрд▓ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЬрд┐рддрдирд╛ рдЕрдзрд┐рдХ рдЖрдк рд╣рд╛рд╕реНрдХреЗрд▓ рдХреЛ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЙрддрдирд╛ рд╣реА рдЖрдк рдЗрд╕ рддрдереНрдп рдХреА рд╕рд░рд╛рд╣рдирд╛ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╕рд┐рджреНрдзрд╛рдВрдд рдЕрдХреНрд╕рд░ рдХрдИ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рдмрд╕реЗ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╕рдорд╛рдзрд╛рди рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдХреЗ рд╕рд╛рде, рдореИрдВ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдЗрд╕ рддрдереНрдп рдкрд░ рдЬреЛрд░ рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рд╣рдо рдЙрдкрд▓рдмреНрдз рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рдиреАрдВрд╡ рдХреЛ рдорд┐рд▓рд╛рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рд╕реНрд╡рдЪреНрдЫ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдЯреНрд░реАрдо рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛рддреЗ рд╣реИрдВред


рдЯрд╛рдЗрдк


рд╣рд╛рд╕реНрдХреЗрд▓ рдПрдХ рдРрд╕реА рднрд╛рд╖рд╛ рд╣реИ рдЬрд╣рд╛рдВ рдкреНрд░рдХрд╛рд░ рдкреНрд░рд╛рдердорд┐рдХ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдзрд╛рд░рд╛рдУрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдкреНрд░рдХрд╛рд░ рдЪреБрдирдХрд░ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдПрдХ рд╕рд░рд▓ рднрд╛рд╖рд╛ рдореЗрдВ рд╕рдВрдХреЗрдд рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдзрд╛рд░рд╛рдПрдБ рд╣рдо рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:

рдЕрдм рд╣рдо рдЗрди рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЛ рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рдЕрдиреБрд╡рд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

рдЗрди рд╢рдмреНрджреЛрдВ рдХреЛ рдПрдХ рд╕рд╛рде рдорд┐рд▓рд╛рдПрдВ, рдФрд░ рдЖрдкрдХреЛ рд╕рд╣реА рдЧрдгрд┐рддреАрдп рд╕рдорд╛рдзрд╛рди рдорд┐рд▓реЗрдЧрд╛: "рдореБрдлреНрдд рдореЛрдирд╛рдб рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░"ред

рд╕рд┐рдВрдЯреЗрдХреНрд╕ рдХрд╛ рдкреЗрдбрд╝

"рдлреНрд░реА рдореЛрдирд╛рдб рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдорд░" рдПрдХ рдЧрдгрд┐рддреАрдп рд╕рд╛рд░ рд╕рд┐рдВрдЯреЗрдХреНрд╕ рдЯреНрд░реА рдХреЗ рд▓рд┐рдП рдПрдХ рдлреИрдВрд╕реА рдирд╛рдо рд╣реИ рдЬрд╣рд╛рдВ рдЕрдиреБрдХреНрд░рдо рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рднреВрдорд┐рдХрд╛ рдирд┐рднрд╛рддрд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдпрд╣ рд╣рдореЗрдВ рдЗрди рдирд┐рд░реНрджреЗрд╢реЛрдВ рд╕реЗ рдПрдХ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╡реГрдХреНрд╖ рдмрдирд╛рддрд╛ рд╣реИред

рд╣рдордиреЗ рдХрд╣рд╛ рдХрд┐ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реА рдзрд╛рд░рд╛ рдпрд╛ рддреЛ рд╢рд╛рдЦрд╛, рдпрд╛ рдирд┐рдпрдВрддреНрд░рдг рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗ, рдпрд╛ рд░реЛрдХреЗ, рддреЛ рдЪрд▓рд┐рдП рдХрд╛рдВрдЯреЗ, рд░рд┐рдЯрд░реНрди рдФрд░ рд╕рдорд╛рдкреНрддрд┐ рдХреЗ рд╕рд╛рде рдПрдХ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ:
{-# LANGUAGE DeriveFunctor #-} data ThreadF next = Fork next next | Yield next | Done deriving (Functor) 

ThreadF рд╣рдорд╛рд░реЗ рдЕрдиреБрджреЗрд╢ рд╕реЗрдЯ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддрд╛ рд╣реИред рд╣рдо рддреАрди рдирдП рдирд┐рд░реНрджреЗрд╢ рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рдереЗ, рдЗрд╕рд▓рд┐рдП рдереНрд░реЗрдбрдПрдл рдХреЗ рдкрд╛рд╕ рддреАрди рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рдХрдорд╛рдВрдб рдХреЗ рд▓рд┐рдП рдПрдХ: Fork , Yield рдФрд░ Done ред

рд╣рдорд╛рд░рд╛ ThreadF рдкреНрд░рдХрд╛рд░ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рдкреЗрдбрд╝ рдореЗрдВ рдПрдХ рдиреЛрдб рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛рдУрдВ рдХреЗ next рдХреНрд╖реЗрддреНрд░ рдпрд╣ рджрд░реНрд╢рд╛рддреЗ рд╣реИрдВ рдХрд┐ рдиреЛрдбреНрд╕ рдХреЗ рдмрдЪреНрдЪреЛрдВ рдХреЛ рдХрд╣рд╛рдБ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред Fork рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреЛ рддрд░реАрдХреЗ рдмрдирд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрд╕рдХреЗ рджреЛ рдмрдЪреНрдЪреЗ рд╣реИрдВред Done рд╡рд░реНрддрдорд╛рди рдирд┐рд╖реНрдкрд╛рджрди рдкрде рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХреА рдХреЛрдИ рд╕рдВрддрд╛рди рдирд╣реАрдВ рд╣реИред Yield рди рддреЛ рд╢рд╛рдЦрд╛рдПрдВ рд╣реЛрддреА рд╣реИрдВ рдФрд░ рди рд╣реА рд╡рд╣ рд╕рдорд╛рдкреНрдд рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрд╕рдХрд╛ рдПрдХ рдмрдЪреНрдЪрд╛ рд╣реИред рд╡реНрдпреБрддреНрдкрдиреНрди (рдлрд╝рдирдХрд╛рд░) рднрд╛рдЧ рдмрд╕ рдореБрдлреНрдд рдореЛрдирд╛рдб рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдХреЛ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ next рдХреНрд╖реЗрддреНрд░ рд╡реЗ рд╣реИрдВ рдЬрд╣рд╛рдБ рдмрдЪреНрдЪреЛрдВ рдХреЛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЬрдм рд╡реНрдпреБрддреНрдкрдиреНрди (рдлрд╝рдирдХрд╛рд░) рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рд▓рдЧрднрдЧ рдХреНрдпрд╛ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
 instance Functor ThreadF where f `fmap` (Fork next next) = Fork (f next) (f next) f `fmap` (Yield next) = Yield (f next) f `fmap` Done = Done 


рдЕрдм рдореБрдлреНрдд FreeT рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ FreeT рд╣рдорд╛рд░реЗ рдХрдорд╛рдВрдб рдХреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╣рдо рдЗрд╕ рдкреЗрдбрд╝ рдХреЛ рдПрдХ рдзрд╛рдЧрд╛ рдХрд╣реЗрдВрдЧреЗ:
 --  `free`  import Control.Monad.Trans.Free type Thread = FreeT ThreadF 

рдПрдХ рдЕрдиреБрднрд╡реА рд╣рд╛рд╕реНрдХреЗрд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдЗрд╕ рдХреЛрдб рдХреЛ рдкрдврд╝реЗрдЧрд╛, рдЬреИрд╕реЗ рдХрд┐ " Thread рдПрдХ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА рд╣реИ рдЬрд┐рд╕реЗ ThreadF рдирд┐рд░реНрджреЗрд╢реЛрдВ рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ ThreadF "

рдЕрдиреБрджреЗрд╢

рдЕрдм рд╣рдореЗрдВ рдЖрджрд┐рдо рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреА рдЬрд░реВрд░рдд рд╣реИред free рдкреИрдХреЗрдЬ liftF рдСрдкрд░реЗрд╢рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рдХрдорд╛рдВрдб рдХреЛ рдПрдХ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА рдореЗрдВ рдПрдХ рдиреЛрдб рдЧрд╣рд░реЗ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИ:
 yield :: (Monad m) => Thread m () yield = liftF (Yield ()) done :: (Monad m) => Thread mr done = liftF Done cFork :: (Monad m) => Thread m Bool cFork = liftF (Fork False True) 

рдЖрдкрдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдХрдорд╛рдВрдб рдХрд╛ рд▓реМрдЯрд╛ рдореВрд▓реНрдп рдЙрд╕ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ рдЬреЛ рд╣рдо рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдб рднрд╛рдЧреЛрдВ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВ:

cFork рдХреЛ рдЗрд╕рдХрд╛ рдирд╛рдо рдЗрд╕рд▓рд┐рдП рдорд┐рд▓рд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ C рд╕реЗ рдПрдХ fork рдлрдВрдХреНрд╢рди рдХреА рддрд░рд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд▓реМрдЯрд╛ рд╣реБрдЖ рдмреВрд▓рд┐рдпрди рд╣рдореЗрдВ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдмреНрд░рд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдХрд┐рд╕ рдмреНрд░рд╛рдВрдЪ рдкрд░ рд╣реИрдВред рдпрджрд┐ рд╣рдо False , рддреЛ рд╣рдо рдмрд╛рдИрдВ рд╢рд╛рдЦрд╛ рдкрд░ рд╣реИрдВ рдФрд░ рдпрджрд┐ рд╣рдо True , рддреЛ рд╣рдо рд╕рд╣реА рд╢рд╛рдЦрд╛ рдкрд░ рд╣реИрдВред

рд╣рдо cFork рдХреЛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдзрд┐рдХ рдкрд╛рд░рдВрдкрд░рд┐рдХ рд╣рд╛рд╕реНрдХреЗрд▓ рд╢реИрд▓реА рдореЗрдВ fork рд▓рд╛рдЧреВ рдХрд░рдХреЗ рдлрд┐рд░ рд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕ рд╕рдореНрдореЗрд▓рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐ рдмрд╛рдИрдВ рд╢рд╛рдЦрд╛ "рдорд╛рддрд╛-рдкрд┐рддрд╛" рд╣реИ рдФрд░ рджрд╛рдИрдВ рд╢рд╛рдЦрд╛ "рдмрдЪреНрдЪрд╛" рд╣реИ:
 import Control.Monad fork :: (Monad m) => Thread ma -> Thread m () fork thread = do child <- cFork when child $ do thread done 

рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб cFork рдХреЙрд▓ cFork , рдФрд░ рдлрд┐рд░ рдпрд╣ рдХрд╣рддрд╛ рд╣реИ, "рдЕрдЧрд░ рдореИрдВ рдПрдХ рдмрдЪреНрдЪрд╛ рд╣реВрдВ, рддреЛ рдХрд╛рдВрдЯреЗ рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдЪрд▓рд╛рдПрдВ рдФрд░ рдлрд┐рд░ рдмрдВрдж рдХрд░ рджреЗрдВ, рдЕрдиреНрдпрдерд╛ рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣ рдЬрд╛рд░реА рд░рдЦреЗрдВред"

рдирд┐: рд╢реБрд▓реНрдХ рднрд┐рдХреНрд╖реБрдУрдВ

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдХреЛрдб рдХреЗ рдЕрдВрддрд┐рдо рдЯреБрдХрдбрд╝реЗ рдореЗрдВ рдХреБрдЫ рдЕрд╕рд╛рдорд╛рдиреНрдп рдХреИрд╕реЗ рд╣реБрдЖред рд╣рдордиреЗ рд╕рдВрдХреЗрддрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдЖрджрд┐рдо Thread рдереНрд░реЗрдб рдирд┐рд░реНрджреЗрд╢реЛрдВ рд╕реЗ cFork рдФрд░ done рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕рдВрдХрд▓рд┐рдд done рдФрд░ рд╣рдореЗрдВ рдирдпрд╛ Thread рд╡рд╛рдкрд╕ рдорд┐рд▓рд╛ред рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╣рд╛рд╕реНрдХреЗрд▓ рд╣рдореЗрдВ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдиреЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдХрд┐ рдореЛрдирд╛рдб рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╣рдорд╛рд░рд╛ рдореБрдлреНрдд рдореЛрдирд╛рдб рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ Thread рд▓рд┐рдП рдореЛрдирд╛рдб instance рд╡рд╛рдВрдЫрд┐рдд instance рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рд╕реНрд╡рд╛рджрд┐рд╖реНрдЯ!

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдорд╛рд░рд╛ рдореБрдлреНрдд рдореЛрдирд╛рдб рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдмрд┐рд▓реНрдХреБрд▓ рд╕реБрдкрд░-рд╕реНрдорд╛рд░реНрдЯ рдирд╣реАрдВ рд╣реИред рдЬрдм рд╣рдо рд╕рдВрдХреЗрддрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдореБрдлреНрдд рдореЛрдирд╛рдб рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдХреЛ рдЗрдХрдЯреНрдард╛ do рд╣реИрдВ, do рдЬреЛ рдХреБрдЫ рднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рд╡рд╣ рдЗрди рдЖрджрд┐рдо рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкреЗрдбрд╝реЛрдВ рдХреЛ рдПрдХ рдиреЛрдб рдЧрд╣рд░реЗ (рдпрд╛рдиреА рдирд┐рд░реНрджреЗрд╢реЛрдВ) рдХреЛ рдПрдХ рдмрдбрд╝реЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИред рджреЛ рдЖрджреЗрд╢реЛрдВ рдХрд╛ рдХреНрд░рдо:
 do yield done 

... рдкрд╣рд▓рд╛ рдХрдорд╛рдВрдб (рдпрд╛рдиреА yield ) рдХреЗ рдПрдХ рдмрдЪреНрдЪреЗ рдХреЗ рд░реВрдк рдореЗрдВ рджреВрд╕рд░рд╛ рдХрдорд╛рдВрдб (рдпрд╛рдиреА done ) рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╕ desaccharizedред

рд▓реВрдк рдкреНрд░рд╡рд╛рд╣ рдкреНрд░рдмрдВрдзрдХ


рдЕрдм рд╣рдо рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдзрд╛рдЧрд╛ рдЕрдиреБрд╕реВрдЪрдХ рд▓рд┐рдЦрдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред рдпрд╣ рдПрдХ рднреЛрд▓рд╛ рдЪрдХреНрд░реАрдп рдЕрдиреБрд╕реВрдЪрдХ рд╣реЛрдЧрд╛:
 --   O(1)      import Data.Sequence roundRobin :: (Monad m) => Thread ma -> m () roundRobin t = go (singleton t) --     where go ts = case (viewl ts) of --   : ! EmptyL -> return () --   :      t :< ts' -> do x <- runFreeT t --     case x of --       Free (Fork t1 t2) -> go (t1 <| (ts' |> t2)) --       Free (Yield t') -> go (ts' |> t') --  :     Free Done -> go ts' Pure _ -> go ts' 

... рдФрд░ рд╣реЛ рдЧрдпрд╛! рдирд╣реАрдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдмрд╛рдд рд╣реИ! рдпрд╣ рдПрдХ рд╕рдВрдкреВрд░реНрдг рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред

рдХрд╕реНрдЯрдо рдзрд╛рдЧреЗ


рдЪрд▓реЛ рд╣рдорд╛рд░реЗ рдирдП рдмрд╣рд╛рджреБрд░ рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред рдЪрд▓реЛ рдХреБрдЫ рд╕рд░рд▓ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред
 mainThread :: Thread IO () mainThread = do lift $ putStrLn "Forking thread #1" fork thread1 lift $ putStrLn "Forking thread #1" fork thread2 thread1 :: Thread IO () thread1 = forM_ [1..10] $ \i -> do lift $ print i yield thread2 :: Thread IO () thread2 = replicateM_ 3 $ do lift $ putStrLn "Hello" yield 

рдЗрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ Thread IO () рдкреНрд░рдХрд╛рд░ Thread IO () ред Thread рдПрдХ "рдореЛрдирдб рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░" рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдпрд╣ рдореМрдЬреВрджрд╛ рдореЛрдирд╛рдб рдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдереНрд░реЗрдбреНрд╕ рдХреЗ рд╕рд╛рде IO рдореЛрдирд╛рдж рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рдмрджрд▓реЗ рдореЗрдВ, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рд░ рдмрд╛рд░ рд╣рдореЗрдВ рдПрдХ IO рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рд╣рдо Thread рдореЗрдВ рдЗрд╕ рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП lift рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

рдЬрдм рд╣рдо roundRobin рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЕрдкрдиреЗ рдереНрд░реЗрдб рдореЛрдирд╛рдб рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдХреЛ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВ, рдФрд░ рд╣рдорд╛рд░реЗ рд╕реНрдЯреНрд░реАрдо рдкреНрд░реЛрдЧреНрд░рд╛рдо IO рдореЗрдВ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдПрдХ рд░реИрдЦрд┐рдХ рдЕрдиреБрдХреНрд░рдо рддрдХ рдврд╣ рдЬрд╛рддреЗ рд╣реИрдВред
 >>> roundRobin mainThread :: IO () Forking thread #1 Forking thread #1 1 Hello 2 Hello 3 Hello 4 5 6 7 8 9 10 

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдорд╛рд░реЗ рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рд╕рд╛рдл рд╣реИ! рд╣рдо рдЕрдиреНрдп рд╕рд╛рдзреБрдУрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рди рдХрд┐ рдХреЗрд╡рд▓ IO , рдФрд░ рдлрд┐рд░ рднреА рд╕реНрдЯреНрд░реАрдо рдкреНрд░рднрд╛рд╡ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ! рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо Writer рдЧрдгрдирд╛ рдХреА рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдБ Writer рдХрдИ рд╢реБрджреНрдз рд╕рд╛рдзреБрдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ (рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рд╣рдм рджреЗрдЦреЗрдВ):
 import Control.Monad.Trans.Writer logger :: Thread (Writer [String]) () logger = do fork helper lift $ tell ["Abort"] yield lift $ tell ["Fail"] helper :: Thread (Writer [String]) () helper = do lift $ tell ["Retry"] yield lift $ tell ["!"] 

рдЬрдм рд╣рдо logger рдЪрд▓рд╛рддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рд╕рдордп roundRobin рдлрд╝рдВрдХреНрд╢рди рдПрдХ рд╢реБрджреНрдз Writer рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддрд╛ рд╣реИ:
 roundRobin logger :: Writer [String] () 

... рдФрд░ рд╣рдо рд▓реЙрдЧрд┐рдВрдЧ рдХрдорд╛рдВрдб рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ:
 execWriter (roundRobin logger) :: [String] 

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдХреИрд╕реЗ рдкреНрд░рдХрд╛рд░ рд╢реБрджреНрдз рдорд╛рди рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ, рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ String рд╕реВрдЪреАред рдФрд░ рд╣рдо рдЕрднреА рднреА рд▓реЙрдЧ рдХрд┐рдП рдЧрдП рдорд╛рдиреЛрдВ рдХреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдзрд╛рд░рд╛рдПрдБ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
 >>> execWriter (roundRobin logger) ["Abort","Retry","Fail","!"] 


рдирд┐рд╖реНрдХрд░реНрд╖


рдЖрдк рд╕реЛрдЪ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдореИрдВ рдПрдХ рдзреЛрдЦреЗрдмрд╛рдЬрд╝ рд╣реВрдБ, рдХрд┐ рдореБрдЦреНрдп рдХрд╛рдо free рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдЪрд▓рд╛ рдЧрдпрд╛, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЬреЛ рднреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ рд╡рд╣ рдмрд╣реБрдд рд╕рд╛рдорд╛рдиреНрдп рдХреЛрдб рдХреА 12 рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рдлрд┐рдЯ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдХрд┐ рдкреБрдирд░реНрдирд╡реАрдиреАрдХрд░рдг рд╣реИред
 data FreeF fax = Pure a | Free (fx) newtype FreeT fma = FreeT { runFreeT :: m (FreeF fa (FreeT fma)) } instance (Functor f, Monad m) => Monad (FreeT fm) where return a = FreeT (return (Pure a)) FreeT m >>= f = FreeT $ m >>= \v -> case v of Pure a -> runFreeT (fa) Free w -> return (Free (fmap (>>= f) w)) instance MonadTrans (FreeT f) where lift = FreeT . liftM Pure liftF :: (Functor f, Monad m) => fr -> FreeT fmr liftF x = FreeT (return (Free (fmap return x))) 

рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рдпрд╣ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рд╡реГрддреНрддрд┐ рд╣реИ: рдЬрдм рд╣рдо рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдПрдХ рдЪреМрдВрдХрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЫреЛрдЯреЗ рдХреЛрдб рдореЗрдВ рдЕрдХреНрд╕рд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдФрд░ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╕рдорд╛рдзрд╛рдиред

рд▓реЗрдЦ рдХрд╛ рд▓реЗрдЦрди рдкреЗрдВрдЧ рд▓реА рдФрд░ рд╕реНрдЯреАрд╡ рдЬрд╝реЗрдбрдВрдЯрд╡рд┐рдЪ рдХреЗ рд▓реЗрдЦ рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рдерд╛, "рд╕реНрдЯреНрд░реАрдо рдФрд░ рдЗрд╡реЗрдВрдЯ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднрд╛рд╖рд╛ рдХреЗ рддрд░реАрдХреЗ"ред рдореБрдЦреНрдп рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдирд┐рд░рдВрддрд░ рддрд░реАрдХреЛрдВ рдХреЛ рдореБрдХреНрдд рдорда рдХреЗ рд╕рд░рд▓ рддрд░реАрдХреЛрдВ рд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

Source: https://habr.com/ru/post/In195274/


All Articles