рдореЛрдирд╛рдж рдХрдВрдЯреНрдЯ рдЗрди рдкрд┐рдХреНрдЪрд░реНрд╕ (рд╣рд╛рд╕реНрдХреЗрд▓)

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


рдЕрдВрджрд░ ContT


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, ContT рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ ред

newtype ContT rma = ContT {runContT :: ((a -> mr) -> mr)} 

рдкреНрд░рдХрд╛рд░ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдХрд┐рд╕реА рддрд░рд╣ рдпрд╣ рддреБрд░рдВрдд рдЕрд╕рд╣рдЬ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ рдХреЙрд▓рд╕реАрд╕реА рдХреЗ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдпрд╣ рдФрд░ рднреА рдЕрд╕рд╣рдЬ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

 callCC :: ((a -> mb) -> ma) -> ma 

рдЪрд▓реЛ рдареАрдХ рд╣реИред
рдЗрд╕рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ "(a-> mr) -> m r" рдХрд╛ рдЪрд░ рд╣реИ, рддреЛ рдпрд╣ рд▓рдЧрднрдЧ рд╡реИрд╕рд╛ рд╣реА рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ "a" рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЪрд░ рд╣реИред рдпрд╣рд╛рдБ рджреЗрдЦреЛред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ тАЬaтАЭ рдФрд░ тАЬa-> mrтАЭ рдХрд╛ рдлрдВрдХреНрд╢рди рд╣реИред рдЖрдк рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд▓рд┐рдП рдЖрд╡реЗрджрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ "рд╢реНрд░реА":
 a -> mr $ a = mr 

рдЕрдм рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ "(a-> mr) -> m r" рдФрд░ рдлрд╝рдВрдХреНрд╢рди "a -> mr" рдХрд╛ рдПрдХ рдЪрд░ рд╣реИред рдЖрдк рдПрдХ рд╕реЗ рджреВрд╕рд░реЗ рддрд░реАрдХреЗ рд╕реЗ рдЖрд╡реЗрджрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдирд╛ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
 (a -> mr) -> mr $ (a -> mr) = mr 

рдЪрд▓рд┐рдП рддрд╕реНрд╡реАрд░реЛрдВ рдХреЛ рдЖрдЧреЗ рдмрдврд╝рд╛рддреЗ рд╣реИрдВред
рдПрдХ рддреАрд░ рдХреЗ рд╕рд╛рде рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╕рд░реНрдХрд▓ рдХреЗ рд╕рд╛рде рд╣рдо рдЯрд╛рдЗрдк "рдП" рдХреЗ рдХреБрдЫ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░реЗрдВрдЧреЗред


"A-> b" рдЬреИрд╕рд╛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рд╕рд░реНрдХрд▓ рдХреА рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдЗрдирдкреБрдЯ рдФрд░ рдПрдХ рдЖрдЙрдЯрдкреБрдЯ рд╣реИ:


рддрдм рд╣рдорд╛рд░рд╛ ContT рд░рд┐рдВрдЧ рдХреА рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:


рдпрджрд┐ рд╣рдо рдлрд╝рдВрдХреНрд╢рди "a-> b" рдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ рддреЛ (a-> mr) -> m r ", рд╣рдо рдЗрд╕реЗ рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реИрдВ:


рдФрд░ рдЕрдм рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рддред рд╣рдореЗрдВ рдпрд╛рдж рд╣реИ рдХрд┐ ContT рдПрдХ рд╕рдиреНрдпрд╛рд╕реА рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд░рд┐рдЯрд░реНрди рдФрд░ рдмрд╛рдЗрдВрдб рдлрд╝рдВрдХреНрд╢рди рдЗрд╕рдХреЗ рд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИрдВред рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдХреНрдпрд╛ рдХрд░рддреЗ рд╣реИрдВред

рд╡рд╛рдкрд╕реА рдХреЗ рд╕рд╛рде , рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред рдпрд╣ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдкрд░рд┐рдгрд╛рдо рд╕реАрдзреЗ рдмрд╛рд╣рд░ рдХреА рдУрд░ рд▓реМрдЯрддрд╛ рд╣реИред
рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

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

рдЙрджрд╛рд╣рд░рдг


рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ

рдорд╛рди рд▓реАрдЬрд┐рдП рд╣рдореЗрдВ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдЦреЛрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЙрд╕рдореЗрдВ рдХрд┐рд╕реА рдЕрдиреНрдп рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо рдкрдврд╝реЗрдВ, рдлрд┐рд░ рдЗрд╕реЗ рдЦреЛрд▓реЗрдВ, рдЗрд╕рдореЗрдВ рддреАрд╕рд░реА рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо рдкрдврд╝реЗрдВ, рддреАрд╕рд░реА рдлрд╝рд╛рдЗрд▓ рдЦреЛрд▓реЗрдВ рдФрд░ рд╕реНрдХреНрд░реАрди рдкрд░ рдореМрдЬреВрдж рд╕рд╛рдордЧреНрд░рд┐рдпреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВред рдЖрдорддреМрд░ рдкрд░ рд╣рдо рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦрддреЗ рдереЗред

 withFileContent :: FilePath -> (String -> IO a) -> IO a withFileContent file fun = withFile file ReadMode $ \h -> hGetContents h >>= fun main = do withFileContent "1.txt" $ \file1_content -> do withFileContent file1_content $ \file2_content -> do withFileContent file2_content $ \file3_content -> do print file3_content 

рдпрд╣рд╛рдВ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдирдИ рдЦреБрд▓реА рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдЗрдВрдбреЗрдВрдЯреЗрд╢рди рдХреИрд╕реЗ рдмрдврд╝рддрд╛ рд╣реИред рдЗрд╕ рдЯреБрдХрдбрд╝реЗ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рддрд╛рдХрд┐ рд╕рднреА рдлрд╛рдЗрд▓реЗрдВ рдПрдХ рд╣реА рдореЛрдирд╛рдб рдХреЗ рдЕрдВрджрд░ рдЦреБрд▓реЗрдВред рдЖрдЗрдП withFileContent рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджреЗрдЦреЗрдВред рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕рдХрд╛ рдкреНрд░рдХрд╛рд░ ContT рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдорд╛рди рд╣реИред рдЪрд▓рд┐рдП ContT monad рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ ред
 doContT cont = runContT cont (const $ return ()) main = doContT $ do file1_content <- ContT $ withFileContent "1.txt" file2_content <- ContT $ withFileContent file1_content file3_content <- ContT $ withFileContent file2_content liftIO $ print file3_content 

рдЗрддрдирд╛ рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ред рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреИрд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛? рдлрд╛рдЗрд▓реЗрдВ рдкрд╣рд▓реЗ рджрд┐рдП рдЧрдП рдЕрдиреБрдХреНрд░рдо рдореЗрдВ рдЦреЛрд▓реА рдЬрд╛рдПрдВрдЧреА, рдлрд┐рд░ рдкрд░рд┐рдгрд╛рдо рд╕реНрдХреНрд░реАрди рдкрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдлрд┐рд░ рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рд░рд┐рд╡рд░реНрд╕ рдСрд░реНрдбрд░ рдореЗрдВ рдмрдВрдж рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ!

рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░, рд╡рд┐рдзреНрд╡рдВрд╕рдХ

рдорд╛рди рд▓реАрдЬрд┐рдП, рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдкрд╣рд▓реЗ рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдХрд╛рдо рдХреЗ рдмрд╛рдж - рд╡рд┐рдзреНрд╡рдВрд╕рдХред рдРрд╕реА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рдХрдХреНрд╖рд╛ рдмрдирд╛рдПрдБред
 class Constructed a where constructor :: a -> IO () destructor :: a -> IO () 

рдЪрд▓реЛ рдХреБрдЫ рдкрд░реАрдХреНрд╖рдг рд╡рд╕реНрддреБ рдмрдирд╛рддреЗ рд╣реИрдВред
 newtype Obj a = Obj a instance (Show a) => Constructed (Obj a) where constructor (Obj a) = putStr $ "constructor for " ++ (show a) ++ "\n" destructor (Obj a) = putStr $ "destructor for " ++ (show a) ++ "\n" 

рд╣рдо ContT рдореЗрдВ рдРрд╕реА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦреЗрдВрдЧреЗ ред рдЕрдм рд╡реЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдирд┐рд░реНрдорд╛рддрд╛ рдФрд░ рд╡рд┐рдзреНрд╡рдВрд╕рдХ (рд░рд┐рд╡рд░реНрд╕ рдСрд░реНрдбрд░ рдореЗрдВ) рдХреЙрд▓ рдХрд░реЗрдВрдЧреЗред
 withConstructed :: (Constructed a) => a -> ContT r IO a withConstructed obj = ContT $ \fun -> do constructor obj rez <- fun obj destructor obj return rez main = doContT $ do a <- withConstructed $ Obj "ObjectA" b <- withConstructed $ Obj "ObjectB" c <- withConstructed $ Obj "ObjectC" liftIO $ putStr "do something\n" {- : constructor for "ObjectA" constructor for "ObjectB" constructor for "ObjectC" do something destructor for "ObjectC" destructor for "ObjectB" destructor for "ObjectA" -} 


рдЗрдВрдЯрд░рдкреНрдЯ рдХрдореНрдкреНрдпреВрдЯрд┐рдВрдЧ

рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдг рдмрд╣реБрдд рд╕рд░рд▓ рдФрд░ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рд╕рдорд╛рди рдереЗред рдФрд░ рд╣рдо рдЧрдгрдирд╛ рдХреЗ рдЕрдВрдд рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд┐рдП рдмрд┐рдирд╛ рдХреБрдЫ рдкрд░рд┐рдгрд╛рдо рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП ContT рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░рддреЗ рд╣реИрдВ? рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ ContT рдореЗрдВ рдХреБрдЫ рдЧрдгрдирд╛ рд╣реИред
 calc :: ContT rm Int calc = do x <- return 10 y <- return $ x*2 z <- return $ x + y return z main = runContT calc print -- : 30 

рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХреИрд▓реНрдХ рдХрд░реЗрдВ
 calc = ContT $ \k -> runContT (do -- <- /  x <- return 10 y <- return $ x*2 z <- return $ x + y return z) k main = runContT calc print -- : 30 

рд╣рдордиреЗ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрджрд▓рд╛, рдмрд╕ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рд▓рдкреЗрдЯ рджрд┐рдпрд╛ред
рдЕрдм рдПрдХ рдкрдВрдХреНрддрд┐ рдЬреЛрдбрд╝реЗрдВред
 calc = ContT $ \k -> runContT (do x <- return 10 y <- return $ x*2 ContT $ \c -> c 5 -- <-   ( "return 5") z <- return $ x + y return z) k main = runContT calc print -- : 30 

рдкрд░рд┐рдгрд╛рдо рдЕрднреА рднреА рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реИред рдЖрд╢реНрдЪрд░реНрдп рдХреА рдмрд╛рдд рдирд╣реАрдВ рд╣реИ, рд▓рд╛рдЗрди "ContT $ \ c -> c 5" рд▓рд╛рдЗрди "рд░рд┐рдЯрд░реНрди 5" рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред
рдФрд░ рдЕрдм рд╕рдмрд╕реЗ рдХрдард┐рди рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред рдЖрдЗрдП тАЬcтАЭ рдХреЛ тАЬkтАЭ рд╕реЗ рдмрджрд▓реЗрдВред
 calc = ContT $ \k -> runContT (do x <- return 10 y <- return $ x*2 ContT $ \c -> k 5 -- <-    "c"  "k" z <- return $ x + y return z) k main = runContT calc print -- <-  "print"   ContT -- : 5 -- <-   

рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдкрд░рд┐рдгрд╛рдо рдЕрдм 5 рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред рдпрд╣рд╛рдВ рдХреНрдпрд╛ рд╣реБрдЖ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред рдЖрдХреГрддрд┐ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред

рдирд╛рд░рдВрдЧреА рд╡рд▓рдп рд╣рдорд╛рд░рд╛ рд╕реНрдерд╛рдиреАрдп рд╡реИрд░рд┐рдПрдмрд▓ c рд╣реИред рдпреЗ рдЧрдгрдирд╛рдПрдВ рд╣реИрдВ рдЬреЛ рд▓рд╛рдЗрди рдХреЗ рдмрд╛рдж рдЬрд╛рддреА рд╣реИрдВ "ContT $ \ c -> k 5"ред рд╣рд░реЗ рд░рдВрдЧ рдХрд╛ рд╕рд░реНрдХрд▓ рд╣рдорд╛рд░рд╛ k рд╡реЗрд░рд┐рдПрдмрд▓ рд╣реИред рдпрджрд┐ рд╣рдо рдХреЛрдб рдореЗрдВ рдЖрдЧреЗ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ "k" рдПрдХ рдкреНрд░рд┐рдВрдЯ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдЕрдзрд┐рдХ рдХреБрдЫ рдирд╣реАрдВ рд╣реИред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдЪрд░ "c" рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рдорд╛рди "5" рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд┐рдВрдЯ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рд╣рдо тАЬcтАЭ рдХреЛ тАЬkтАЭ рд╕реЗ рдмрджрд▓рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдирд┐рдореНрди рдЪрд┐рддреНрд░ рдорд┐рд▓рддреЗ рд╣реИрдВред

рдЕрдм рд╣рдо рдмрд╛рдж рдХреА рд╕рднреА рдЧрдгрдирд╛рдУрдВ рдХреЛ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рддреБрд░рдВрдд "рдкреНрд░рд┐рдВрдЯ" рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдорд╛рди рдХреЛ "5" рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВ рдЕрдм рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдирд╣реАрдВ рдмрджрд▓реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдмрд╕ рд╕рдорд╛рди рдХреЛрдб рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░реЗрдЧрд╛ред рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо "рдирд┐рд░рдВрддрд░" 5 "рдмреНрд░реИрдХреЗрдЯ" рдХрд░реЗрдВрдЧреЗред
 calc = ContT $ \k -> runContT (do x <- return 10 y <- return $ x*2 (\a -> ContT $ \c -> ka) 5 -- <-    "a" z <- return $ x + y return z) k 

рдХреЛрд╖реНрдардХ рд▓реИрдВрдмрдбрд╛ "(\ a -> ContT $ \ c -> ka)"ред
 calc = ContT $ \k -> runContT ((\exit -> do -- <-    "exit" x <- return 10 y <- return $ x*2 exit 5 z <- return $ x + y return z) (\a -> ContT $ \c -> ka)) k 

рдЕрдм рд╣рдо рдкреВрд░реЗ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди "\ exit -> do ... return z" рдХреЛ рдирд┐рдХрд╛рд▓реЗрдВрдЧреЗред
 calc = (\f -> ContT $ \k -> runContT (f (\a -> ContT $ \c -> ka)) k) $ \exit -> do -- ^    "f" x <- return 10 y <- return $ x*2 exit 5 z <- return $ x + y return z 

рд╢рд░реАрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрд▓рдЧ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ "(\ f -> ContT ... ka)) k)"ред рд╡реИрд╕реЗ, рдмрдзрд╛рдИ! рд╣рдордиреЗ рд╕рд┐рд░реНрдл рдмрд╛рдЗрдХ рдХреЙрд▓рд╕реАрд╕реА рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд┐рдпрд╛ред
 callCC f = ContT $ \k -> runContT (f (\a -> ContT $ \_ -> ka)) k calc = callCC $ \exit -> do -- <-     "callCC" x <- return 10 y <- return $ x*2 exit 5 z <- return $ x + y return z 

рдмреЗрд╢рдХ, рдХрд╛рд░реНрдпрдХреНрд░рдо рдмрд┐рд▓реНрдХреБрд▓ рдмреЗрд╡рдХреВрдл рдирд┐рдХрд▓рд╛, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╣рдордиреЗ рдЧрдгрдирд╛ рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рдирд╛ рд╕реАрдЦрд╛ред

рдкреБрдирд╢реНрдЪ


рдореИрдВрдиреЗ рдЙрд╕реА рддрд░рд╣ рд╕реЗ getCC рдлрд╝рдВрдХреНрд╢рди рдмреЙрдбреА рдХреЛ рдирд┐рдХрд╛рд▓рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдФрд░ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рджрд┐рдорд╛рдЧ рдирд╣реАрдВ рдерд╛ред рд╢рд╛рдпрдж рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

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


All Articles