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

рдЯрд╛рдЗрдк
рд╣рд╛рд╕реНрдХреЗрд▓ рдПрдХ рдРрд╕реА рднрд╛рд╖рд╛ рд╣реИ рдЬрд╣рд╛рдВ рдкреНрд░рдХрд╛рд░ рдкреНрд░рд╛рдердорд┐рдХ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдзрд╛рд░рд╛рдУрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдкреНрд░рдХрд╛рд░ рдЪреБрдирдХрд░ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдПрдХ рд╕рд░рд▓ рднрд╛рд╖рд╛ рдореЗрдВ рд╕рдВрдХреЗрдд рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдзрд╛рд░рд╛рдПрдБ рд╣рдо рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:
- рдзрд╛рд░рд╛рдУрдВ рдХреЛ рдореМрдЬреВрджрд╛ рдЕрдиреБрджреЗрд╢ рдЕрдиреБрдХреНрд░рдо рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
- рдереНрд░реЗрдбреНрд╕ рдХреЛ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдПрдХ рд╕реЗрдЯ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП: рдмреНрд░рд╛рдВрдЪрд┐рдВрдЧ, рдирд┐рдпрдВрддреНрд░рдг рд╣рд╕реНрддрд╛рдВрддрд░рдг рдФрд░ рд╕рдорд╛рдкреНрддрд┐
- рдереНрд░реЗрдбреНрд╕ рдХреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рд╢реЗрдбреНрдпреВрд▓рд░реНрд╕ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреА рдЪрд╛рд╣рд┐рдП
рдЕрдм рд╣рдо рдЗрди рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЛ рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рдЕрдиреБрд╡рд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
- рдЬрдм рдЖрдк "рдХрдИ рджреБрднрд╛рд╖рд┐рдпреЛрдВ / рдпреЛрдЬрдирд╛рдХрд╛рд░реЛрдВ / рдмреИрдХреЗрдВрдбреНрд╕" рдХреЛ рд╕реБрдирддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ "рд╕реНрд╡рддрдВрддреНрд░" (рдЬреИрд╕рд╛ рдХрд┐ "рдореБрдХреНрдд рд╡рд╕реНрддреБ") рд╕реЛрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП
- рдЬрдм рдЖрдк "рдЖрджреЗрд╢реЛрдВ рдХрд╛ рдХреНрд░рдо" рд╕реБрдирддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдпрд╣ рд╕реЛрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП: "рднрд┐рдХреНрд╖реБред"
- рдЬрдм рдЖрдк рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХрд╛ "рд╡рд┐рд╕реНрддрд╛рд░" рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рд╕реЛрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП: "рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░"ред
рдЗрди рд╢рдмреНрджреЛрдВ рдХреЛ рдПрдХ рд╕рд╛рде рдорд┐рд▓рд╛рдПрдВ, рдФрд░ рдЖрдкрдХреЛ рд╕рд╣реА рдЧрдгрд┐рддреАрдп рд╕рдорд╛рдзрд╛рди рдорд┐рд▓реЗрдЧрд╛: "рдореБрдлреНрдд рдореЛрдирд╛рдб рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░"ред
рд╕рд┐рдВрдЯреЗрдХреНрд╕ рдХрд╛ рдкреЗрдбрд╝
"рдлреНрд░реА рдореЛрдирд╛рдб рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдорд░" рдПрдХ рдЧрдгрд┐рддреАрдп рд╕рд╛рд░ рд╕рд┐рдВрдЯреЗрдХреНрд╕ рдЯреНрд░реА рдХреЗ рд▓рд┐рдП рдПрдХ рдлреИрдВрд╕реА рдирд╛рдо рд╣реИ рдЬрд╣рд╛рдВ рдЕрдиреБрдХреНрд░рдо рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рднреВрдорд┐рдХрд╛ рдирд┐рднрд╛рддрд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдпрд╣ рд╣рдореЗрдВ рдЗрди рдирд┐рд░реНрджреЗрд╢реЛрдВ рд╕реЗ рдПрдХ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╡реГрдХреНрд╖ рдмрдирд╛рддрд╛ рд╣реИред
рд╣рдордиреЗ рдХрд╣рд╛ рдХрд┐ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реА рдзрд╛рд░рд╛ рдпрд╛ рддреЛ рд╢рд╛рдЦрд╛, рдпрд╛ рдирд┐рдпрдВрддреНрд░рдг рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗ, рдпрд╛ рд░реЛрдХреЗ, рддреЛ рдЪрд▓рд┐рдП рдХрд╛рдВрдЯреЗ, рд░рд┐рдЯрд░реНрди рдФрд░ рд╕рдорд╛рдкреНрддрд┐ рдХреЗ рд╕рд╛рде рдПрдХ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ:
{-# 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
рд╣рдорд╛рд░реЗ рдХрдорд╛рдВрдб рдХреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╣рдо рдЗрд╕ рдкреЗрдбрд╝ рдХреЛ рдПрдХ рдзрд╛рдЧрд╛ рдХрд╣реЗрдВрдЧреЗ:
рдПрдХ рдЕрдиреБрднрд╡реА рд╣рд╛рд╕реНрдХреЗрд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдЗрд╕ рдХреЛрдб рдХреЛ рдкрдврд╝реЗрдЧрд╛, рдЬреИрд╕реЗ рдХрд┐ "
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)
рдЖрдкрдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдХрдорд╛рдВрдб рдХрд╛ рд▓реМрдЯрд╛ рдореВрд▓реНрдп рдЙрд╕ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ рдЬреЛ рд╣рдо рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдб рднрд╛рдЧреЛрдВ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВ:
yield
рдХрдорд╛рдВрдб рдЙрд╕рдХреЗ рдмрдЪреНрдЪреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдмрдЪрд╛рддрд╛ рд╣реИ ()
, рдЗрд╕рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд░рд┐рдЯрд░реНрди рдорд╛рди рд╣реИ ()
done
рдЖрджреЗрд╢ рдореЗрдВ рдХреЛрдИ рд╕рдВрддрд╛рди рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╕рдВрдХрд▓рдХ рдХрд╛ рдХрд╣рдирд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рдПрдХ рдмрд╣реБрд░реВрдкрд┐рдХ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп (рдпрд╛рдиреА r
) рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдпрд╣ рдХрднреА рдЦрддреНрдо рдирд╣реАрдВ рд╣реЛрдЧрд╛cFork
рдХрдорд╛рдВрдб рдмрдЪреНрдЪреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ cFork
рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдПрдХ Bool
рд▓реМрдЯрд╛рддрд╛ рд╣реИ
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ред
рд▓реВрдк рдкреНрд░рд╡рд╛рд╣ рдкреНрд░рдмрдВрдзрдХ
рдЕрдм рд╣рдо рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдзрд╛рдЧрд╛ рдЕрдиреБрд╕реВрдЪрдХ рд▓рд┐рдЦрдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред рдпрд╣ рдПрдХ рднреЛрд▓рд╛ рдЪрдХреНрд░реАрдп рдЕрдиреБрд╕реВрдЪрдХ рд╣реЛрдЧрд╛:
... рдФрд░ рд╣реЛ рдЧрдпрд╛! рдирд╣реАрдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдмрд╛рдд рд╣реИ! рдпрд╣ рдПрдХ рд╕рдВрдкреВрд░реНрдг рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред
рдХрд╕реНрдЯрдо рдзрд╛рдЧреЗ
рдЪрд▓реЛ рд╣рдорд╛рд░реЗ рдирдП рдмрд╣рд╛рджреБрд░ рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред рдЪрд▓реЛ рдХреБрдЫ рд╕рд░рд▓ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред
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)))
рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рдпрд╣ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рд╡реГрддреНрддрд┐ рд╣реИ: рдЬрдм рд╣рдо рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдПрдХ рдЪреМрдВрдХрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЫреЛрдЯреЗ рдХреЛрдб рдореЗрдВ рдЕрдХреНрд╕рд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдФрд░ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╕рдорд╛рдзрд╛рдиред
рд▓реЗрдЦ рдХрд╛ рд▓реЗрдЦрди рдкреЗрдВрдЧ рд▓реА рдФрд░ рд╕реНрдЯреАрд╡ рдЬрд╝реЗрдбрдВрдЯрд╡рд┐рдЪ рдХреЗ рд▓реЗрдЦ рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рдерд╛, "рд╕реНрдЯреНрд░реАрдо рдФрд░ рдЗрд╡реЗрдВрдЯ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднрд╛рд╖рд╛ рдХреЗ рддрд░реАрдХреЗ"ред рдореБрдЦреНрдп рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдирд┐рд░рдВрддрд░ рддрд░реАрдХреЛрдВ рдХреЛ рдореБрдХреНрдд рдорда рдХреЗ рд╕рд░рд▓ рддрд░реАрдХреЛрдВ рд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред