рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рджреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рдПрдХ-рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рд╕рдВрд╡рд╛рдж рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡реЗ рдЙрддреНрддрд░ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрддреНрддрд░ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдХреНрд░рдо рдореЗрдВ рдЖрддреЗ рд╣реИрдВред рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдирдВрдмрд░ рд╕рдВрджреЗрд╢ рдХреЗ рд╕рд╛рде рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореВрд▓ (рдЬрд┐рд╕ рдкрд░ рд╣рдо рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддреЗ рд╣реИрдВ) рд╕рдВрджреЗрд╢ рдХреА рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдмрд╛рдж рдХреЗ рд╕рдВрдЪрд╛рд░ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдВрдЦреНрдпрд╛ рднреЗрдЬрддреА рд╣реИред
рд╣рдорд╛рд░рд╛ рд▓рдХреНрд╖реНрдп рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рднреЗрдЬрдиреЗ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рд╣реИ, рдЬрдм рдХреБрдЫ рд╡рд╛рд░реНрддрд╛рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╕рдВрд╡рд╛рдж рдХрд░рдирд╛, рдФрд░ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рднреЗрдЬрдиреЗ рдХреЗ рдмреАрдЪ I / O (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдбреЗрдЯрд╛рдмреЗрд╕ рддрдХ рдкрд╣реБрдВрдЪ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреА рдкрд╕рдВрджреАрджрд╛ рднрд╛рд╖рд╛ рдореЗрдВ рдХреЛрдб рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХрд╛ рдПрдХ рд╕рдВрд╡рд╛рдж, рдЗрд╕ рддрдереНрдп рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдХрд┐ рдХрд┐рд╕реА рднреА рд╕рдордп (рдЗрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рднреА рдЖрдЗрдЯрдо рдХреЗ рдмреАрдЪ) рдХреБрдЫ рдЕрдиреНрдп рдЕрдиреБрд░реЛрдз рдЖ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЧрд▓рддреА рд╕реЗ рдЗрд╕ рд╕рдВрд╡рд╛рдж рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП :
1. рдирдВрдмрд░ рднреЗрдЬреЗрдВ
2. рдЬрд╡рд╛рдм рдореЗрдВ рдирдВрдмрд░ рдЖрддрд╛ рд╣реИ
3. рд╣рдо рд╕рдВрдЦреНрдпрд╛ 2 рдЦрдВрдб рд╕реЗ рднреЗрдЬрддреЗ рд╣реИрдВ
4. рдЙрддреНрддрд░ рдлрд┐рд░ рд╕реЗ рд╕рдВрдЦреНрдпрд╛ рд╣реИ
5. рд╣рдо рдХрдВрд╕реЛрд▓ рдореЗрдВ рд╕рдВрдЦреНрдпрд╛ 2 рдФрд░ рдЦрдВрдб 4 рдореЗрдВ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХрд╛ рдпреЛрдЧ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ
рдпрд╣ рдЗрд╕ рддрд░рд╣ рд╣рд╛рд╕реНрдХреЗрд▓ рдкрд░ рджрд┐рдЦреЗрдЧрд╛ (
example
рдлрд╝рдВрдХреНрд╢рди, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рд╣реИ):
example :: Int -> AIO () <br>
example v = do <br>
x <- request v<br>
y <- request ( x * x ) <br>
io $ print ( x + y ) <br>
рдПрдХ рдЕрд╡рд░реБрджреНрдз рд╕рдорд╛рди рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдЗрд╕рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВ, рдЬреЛ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИ:
example :: Int -> IO () <br>
example v = do <br>
x <- request v<br>
y <- request ( x * x ) <br>
print ( x + y ) <br>
рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╡рд┐рд╡рд░рдгреЛрдВ рд╕реЗ рд╡рд┐рдЪрд▓рд┐рдд рдирд╣реАрдВ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдХрдИ рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдореИрдВ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХреЛ рд╕рд░рд▓ рдХрд░ рджреВрдВрдЧрд╛ред рд╣рдо рдЪреИрдирд▓ (
Chan a
) рдХреЛ рдкрдврд╝реЗрдВрдЧреЗ рдФрд░ рд▓рд┐рдЦреЗрдВрдЧреЗ, рдФрд░ рд╕рдВрджреЗрд╢ рдЯрд╛рдЗрдк
(Int, String)
, рдЕрд░реНрдерд╛рдд рд╕рдВрджреЗрд╢ рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдХреНрд░рдордмрджреНрдз рдореВрд▓реНрдпред
рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдореЙрдбреНрдпреВрд▓ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ:
> module Test ( <br>
> ) where <br>
> <br>
> import Control . Arrow <br>
> import Control . Monad <br>
> import Control . Concurrent . MVar <br>
> import Control . Concurrent . Chan <br>
> import Control . Concurrent <br>
> import Data . List <br>
> import Data . Maybe <br>
рд╕рдиреНрдпрд╛рд╕реА рд▓рд┐рдЦрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдХреЙрд▓рдмреИрдХ рдкрд░ рд╕рдм рдХреБрдЫ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред
рд╕рдВрджреЗрд╢ рднреЗрдЬрддреЗ рд╕рдордп, рд╣рдореЗрдВ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдирдВрдмрд░ рдЬреЗрдирд░реЗрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рд╕рд╛рде рд╣реА рд╕реВрдЪреА рдореЗрдВ рдХреЙрд▓рдмреИрдХ рднреА рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред рдпрд╛рдиреА рд╣рдореЗрдВ рдПрдХ рдЪрд░ рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдЬреЛрдбрд╝реЗ
рд╕рдВрдЦреНрдпрд╛ ->
рдХреЙрд▓рдмреИрдХ рдХреА рд╕реВрдЪреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рд╣рдореЗрдВ рднреА, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕реНрд╡рдпрдВ рдЪреИрдирд▓реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕реЙрдХреЗрдЯ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЙрдиреНрд╣реЗрдВ рджреЛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдПрдХ рдХреЛ рд▓рд┐рдЦреЗрдВрдЧреЗ, рдФрд░ рджреВрд╕рд░реЗ рд╕реЗ рдкрдврд╝реЗрдВрдЧреЗред рд╣рдо рдпрд╣ рд╕рдм рдПрдХ рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░реЗрдВрдЧреЗ:
> data AState = AState { <br>
> aCurrent :: MVar Int , <br>
> aWait :: MVar [ ( Int , String -> IO () ) ] , <br>
> aChanOut :: Chan ( Int , String ) , <br>
> aChanIn :: Chan ( Int , String ) } <br>
> <br>
> newA = liftM4 AState ( newMVar 0 ) ( newMVar [] ) newChan newChan<br>
рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рд╕рдВрджреЗрд╢ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдЪреИрдирд▓ рд╕реЗ рдкрдврд╝рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдХреЙрд▓рдмреИрдХ рдХреЛ рд╕рдВрджреЗрд╢ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
рд╣рдо рдЪреИрдирд▓ рд╕реЗ рдкрдврд╝реЗрдВрдЧреЗ, рдлрд┐рд░ рдПрдХ рдЙрдкрдпреБрдХреНрдд рдХреЙрд▓рдмреИрдХ (рд╕реВрдЪреА рд╕реЗ рдЗрд╕реЗ рд╣рдЯрд╛рддреЗ рд╕рдордп) рдФрд░ рдХреЙрд▓ рджреЗрдЦреЗрдВред рдпрд╣ рд╕рд░рд▓ рд╣реИ:
> listener ( AState _ w _ chIn ) = forever $ do <br>
> ( i , s ) <- readChan chIn<br>
> -- modifyMVar a -> IO (a, b) <br>
> -- .. , . <br>
> -- callback. <br>
> callback <- modifyMVar w $ \ callbacks -> do <br>
> -- callback' . <br>
> let ( past , ok ) = partition ( ( /= i ) . fst ) callbacks<br>
> -- ( ). <br>
> case ok of <br>
> ( ( _ , f ) : _ ) -> return ( past , f ) -- callback ( ). <br>
> _ -> return ( past , \ s -> return () ) -- , <br>
> callback s -- callback. <br>
рддрд╛рдХрд┐ "рд╕рд░реНрд╡рд░" рдкрд░ рдкрд╣реБрдВрдЪрдиреЗ рд╡рд╛рд▓реЗ рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдкрд╣рд▓реА рдмрд╛рд░ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХреЗ, рд╣рдо рдПрдХ рд╣реИрдВрдбрд▓рд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ рдЖрдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рд╣рдорд╛рд░реЗ рд╡рд╛рд░реНрддрд╛рдХрд╛рд░ (
aChanOut
рдЪреИрдирд▓ рдореЗрдВ) рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░реЗрдЧрд╛ред
рд╣рдо
aChanOut
рдЪреИрдирд▓ рдФрд░ рдбрд┐рд╕реНрдкреНрд▓реЗ рд╕реЗ рдкрдврд╝рддреЗ рд╣реИрдВ:
> tracer ( AState _ _ chOut _ ) = forever $ readChan chOut >>= print<br>
рдкреНрд░реЛрдореЛрдирд╛рдбрд┐рдХ рддрд░реАрдХрд╛
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдмрд┐рдирд╛ рдХрд┐рд╕реА рдореЛрдирд╛рдб рдХреЗ рдХрд░реЗрдВрдЧреЗред рдПрдХ рд╕рдВрджреЗрд╢ рднреЗрдЬрдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдХрд░рддреЗ рд╣реИрдВред
рдпрд╣ рдПрдХ рд╕рдВрджреЗрд╢ рд╕рдВрдЦреНрдпрд╛ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рд╕рдВрджреЗрд╢ рдХреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдХреНрд░рдордмрджреНрдз рдХрд░реЗрдВ, рдФрд░ рдХреЙрд▓рдмреИрдХ рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВред
sendAndReceive1 :: AState -> String -> ( String -> IO () ) -> IO () <br>
sendAndReceive1 ( AState cur w chOut _ ) msg onMsg = do <br>
i <- modifyMVar cur ( return . ( succ &&& id ) ) -- 1 . <br>
modifyMVar_ w ( return . ( ( i , onMsg ) : ) ) -- callback. <br>
writeChan chOut ( i , msg ) -- . <br>
рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИ, рд▓реЗрдХрд┐рди рдХреБрдЫ рдЦрд╛рдорд┐рдпрд╛рдВ рд╣реИрдВ:
sendAndReceive1 a ( show 123 ) $ \ ans -> do <br>
let x = read ans -- . <br>
print x<br>
sendAndReceive1 a ( show x ) $ \ ans2 -> do <br>
-- ... <br>
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдк рдХреНрд░рдорд╛рдВрдХрди рдФрд░
sendAndReceive2
рдХреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдХреЙрд▓рдмреИрдХ рдореЗрдВ рди рд▓рд┐рдЦреЗрдВ рдФрд░
sendAndReceive2
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ
sendAndReceive2
, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдорд╛рдирдХ
read
рдФрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ
show
ред
sendAndReceive1 :: AState -> a -> ( a -> String ) -> ( String -> b ) -> ( b -> IO () ) -> IO () <br>
sendAndReceive1 ( AState cur w chOut _ ) msg show_ read_ onMsg = do <br>
i <- modifyMVar cur ( return . ( succ &&& id ) ) <br>
modifyMVar_ w ( return . ( ( i , onMsg . read_ ) : ) ) <br>
writeChan chOut ( i , show_ msg ) <br>
<br>
sendAndReceive2 :: ( Show a , Read b ) => AState -> a -> ( b -> IO () ) -> IO () <br>
sendAndReceive2 a msg onMsg = sendAndReceive1 a msg show read onMsg<br>
<br>
-- . <br>
sendAndReceive2 a 23 $ \ x -> do <br>
print x<br>
sendAndReceive2 a ( x + 10 ) $ \ z -> ... <br>
рдЗрд╕ рдкрд░ рдирд┐рд╡рд╛рд╕ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди
рддрдм рдЕрд╕реЗрдВрдмрд▓рд░ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд▓реЗрдирд╛ рд╕рдВрднрд╡ рдерд╛, рдЗрд╕рд▓рд┐рдП рд╡рд╣рд╛рдВ рдПрдХ рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЕрдореВрд░реНрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛?
Eumonadic рддрд░реАрдХрд╛
рдпрджрд┐ рд╣рдо рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдореЛрдирд╛рдб рдХрд╛ рдореБрдЦреНрдп рдХрд╛рд░реНрдп (рдЯреАрд╕реА рдореЗрдВ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ) рдЯрд╛рдЗрдк
ma -> (a -> mb) -> mb
, рддреЛ рд╣рдорд╛рд░рд╛ рдХреЙрд▓рдмреИрдХ рджреВрд╕рд░реЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рднреАрдЦ рдорд╛рдБрдЧрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рд╡рд╣рд╛рдВ рдЯрд╛рдЗрдк
print
рдХреА рдирд┐рдпрдорд┐рдд рдЧрдгрдирд╛ рдХрд░рдиреЗ рдореЗрдВ рднреА рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЙрдиреНрд╣реЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рджреЛ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдирдпрд╛ рдкреНрд░рдХрд╛рд░ рдмрдирд╛рдПрдВ:
1. рд╕рдВрджреЗрд╢ + рдХреЙрд▓рдмреИрдХ
2. рд╢реБрджреНрдз рдореВрд▓реНрдп
> data AS a = Send String ( String -> AIO a ) | Pure a<br>
рдФрд░ рдЗрд╕реЗ
IO
рд╕рдирдж рдореЗрдВ рд▓рдкреЗрдЯреЗрдВред
> data AIO a = AIO { aio :: IO ( AS a ) } <br>
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдорд╛рд░реА рдЧрдгрдирд╛ рдХреЛ рджреЛ рд╢рд┐рд╡рд┐рд░реЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛: рдПрдХ рд╕рдВрджреЗрд╢ рднреЗрдЬрдирд╛ рдФрд░ рдмрд╛рдХреА рд╕рднреАред
рд╣рдо рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рд╣рдорд╛рд░реЗ рдорда рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп
IO
рдХреЛ "рдЙрдард╛рддрд╛ рд╣реИ"ред рдЗрд╕реЗ
IO
рдХреЗ рд╕рдорд╛рди рд╣реА рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдЗрд╕реЗ
Pure
рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рд▓рдкреЗрдЯрдирд╛ рдЪрд╛рд╣рд┐рдП
> io :: IO a -> AIO a<br>
<br>
io act = AIO $ do <br>
v <- act<br>
return ( Pure v ) <br>
рдпрд╛ рдЖрд╕рд╛рди:
> io = AIO . liftM Pure <br>
рд╕рдВрджреЗрд╢ рднреЗрдЬрдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рджреВрд╕рд░реЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛ -
Send
, рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рддрд░реНрдХреЛрдВ рдХреЛ рдкреИрдХ рдХрд░рдирд╛:
> sendAndReceive :: a -> ( a -> String ) -> ( String -> b ) -> AIO b<br>
> sendAndReceive msg to from = AIO $ return $ Send ( to msg ) ( return . from ) <br>
рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ
request
,
show
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдХреНрд░рдорд╛рдВрдХрди рдХреЗ рд▓рд┐рдП
read
:
> request :: ( Show a , Read b ) => a -> AIO b<br>
> request msg = sendAndReceive msg show read<br>
рдХреБрдЫ рддрд░рдХреАрдм рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдЕрдкрдиреЗ рдорда рдореЗрдВ рдХрд┐рд╕реА рдЪреАрдЬ рдХреА рдЧрдгрдирд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдПрдХ рдЧрдгрдирд╛ рд╡реГрдХреНрд╖ рдХреА рддрд░рд╣ рдХреБрдЫ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╣реИрдВред рдЕрдкрдиреЗ рдЖрдк рд╕реЗ, рдпреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЗрд╡рд▓
AIO
рдкреНрд░рдХрд╛рд░ рдмрдирд╛рддреЗ рд╣реИрдВред
рдпрд╣ рдПрдХ рдРрд╕рд╛ рдлрдВрдХреНрд╢рди рд▓реЗрдиреЗ рдХрд╛ рд╕рдордп рд╣реИ рдЬреЛ рдЗрд╕ рд╕рд╛рд░реЗ рдХрдЪрд░реЗ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрд╛рдиреА рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рд╕рдВрд╡рд╛рдж рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
example
)ред рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╕рдВрд╡рд╛рдж рджреЛ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдореЗрдВ рдЖрддрд╛ рд╣реИ:
1.
Pure
- рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдореВрд▓реНрдп рдирд┐рдХрд╛рд▓рдиреЗ рдФрд░ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
2.
Send
- рдпрд╣рд╛рдВ рдореБрдЦреНрдп рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рд╣рдо рдПрдХ рдирдВрдмрд░ рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВ, рдХреЙрд▓рдмреИрдХ рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рд╕рдВрджреЗрд╢ рднреЗрдЬрддреЗ рд╣реИрдВред
> run :: AState -> AIO () -> IO () <br>
> run a @ ( AState cur w chOut chIn ) act = run' act where <br>
> run' ( AIO actIO ) = do <br>
> as <- actIO<br>
> case as of <br>
> Pure value -> return value<br>
> Send msg onMsg -> do <br>
> i <- modifyMVar cur ( return . ( succ &&& id ) ) -- <br>
> modifyMVar_ w ( return . ( ( i , run' . onMsg ) : ) ) -- callback. <br>
> writeChan chOut ( i , msg ) -- . <br>
рдЕрдм рд╕рдм рдХреБрдЫ
instance
рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИ:
> instance Monad AIO where <br>
> return = AIO . return . Pure -- <br>
> AIO v >>= f = AIO $ do <br>
> x <- v -- AS, Send Pure? <br>
> case x of <br>
> -- Pure, callback . <br>
> Pure value -> aio $ f value<br>
> -- "" callback . <br>
> Send msg onMsg -> return $ Send msg ( \ s -> onMsg s >>= f ) <br>
рдЖрдЦрд┐рд░реА рдЪреАрдЬ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдП рд╡рд╣ рд╣реИ рдСрдкрд░реИрдЯрд┐рдмрд┐рд▓рд┐рдЯреА рдЪреЗрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрдВрдХреНрд╢рди, рдЬреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдЗрдирдХрдорд┐рдВрдЧ рдореИрд╕реЗрдЬ рдХреЛ рдкреНрд░реЛрд╕реЗрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
listener
рдереНрд░реЗрдб рд╢реБрд░реВ рдХрд░реЗрдЧрд╛ рдФрд░ рд╕рд░реНрд╡рд░ рдкрд░ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдореИрд╕реЗрдЬ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
tracer
рдХрд░реЗрдЧрд╛ рдФрд░ рд╕рд░реНрд╡рд░ рд╕реЗ рдореИрд╕реЗрдЬ рдХреЛ рд╣рдорд╛рд░реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╡рд╛рдкрд╕ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрдВрдХреНрд╢рди рд▓реМрдЯрд╛рдПрдЧрд╛ред рдпрд╛рдиреА рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рд╕реНрд╡рдпрдВ рдПрдХ рд╡рд╛рд░реНрддрд╛рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░реЗрдВрдЧреЗ, рдЬрд┐рд╕реЗ рд╣рдо рдЕрдкрдиреЗ рдЧреНрд░рд╛рд╣рдХ рдХреЛ рднреЗрдЬрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:
> start :: IO ( AState , ( Int , String ) -> IO () ) <br>
> start = newA >>= forks where <br>
> forks a = mapM_ forkIO [ listener a , tracer a ] >> return ( a , writeChan ( aChanIn a ) ) <br>
Tydysch!
рдЕрдм рдЖрдк рдореВрд▓ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджреБрднрд╛рд╖рд┐рдпрд╛ рдореЗрдВ рдЗрд╕реЗ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
-- , - <br>
-- , <br>
ghci > ( a , f ) <- start<br>
-- <br>
ghci > run a ( example 10 ) <br>
-- <br>
( 0 , "10" ) <br>
-- <br>
ghci > run a ( example 20 ) <br>
-- , <br>
( 1 , "20" ) <br>
-- "" <br>
ghci > f ( 0 , "11" ) <br>
-- <br>
( 2 , "121" ) <br>
-- "" <br>
ghci > f ( 1 , "21" ) <br>
-- <br>
( 3 , "441" ) <br>
-- "", , "" <br>
ghci > f ( 3 , "444" ) <br>
-- <br>
465 <br>
-- "" <br>
ghci > f ( 2 , "122" ) <br>
133 <br>
ghci > <br>
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдПрдХ рд╣реА рдмрд╛рд░ рдореЗрдВ рджреЛ
example
рдХреЗ рд▓реЙрдиреНрдЪ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдЙрдирдХреЗ рд╕рд╛рде рд╕рдВрд╡рд╛рдж рдПрдХ рджреВрд╕рд░реЗ рдХреЛ рдирд╣реАрдВ рдХрд╛рдЯрддрд╛ рд╣реИред
рд╡реИрд╕реЗ, рдпрд╣ рд╕рдм рд╕рдВрджреЗрд╢
test.lhs
рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рдПрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╣реИ, рдЖрдк рдЗрд╕реЗ рдЯреЗрд╕реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрдкреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
PS рдЗрд╕ рд▓реЗрдЦ рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдореЗрдВ
рдореЗрд░реА рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
pechlambda рдХрд╛ рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рджред