module Lessons.Lesson06 where
import Control.Concurrent (newChan, threadDelay, forkIO,readChan, writeChan, Chan)
import System.Random
import Control.Concurrent.STM
( TVar, writeTVar, newTVarIO, modifyTVar )
import Control.Monad.STM
import Control.Concurrent.STM.TVar (readTVar, readTVarIO)
import Control.Concurrent.Async
import Control.Monad (when)
main :: IO ()
main :: IO ()
main = String -> IO ()
putStrLn String
"Hello, Haskell!"
main' :: IO String
main' :: IO String
main' = IO String
getLine
m :: IO ()
m :: IO ()
m = do
String
line <- IO String
getLine
String -> IO ()
putStrLn String
line
queryName :: IO String
queryName :: IO String
queryName = do
String -> IO ()
putStrLn String
"What is your name?"
IO String
getLine
aGame :: IO ()
aGame :: IO ()
aGame = do
String
name <- IO String
queryName
let salute :: String
salute = String
"Hello, " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"!"
String -> IO ()
putStrLn String
salute
pureF :: String -> IO String
pureF :: String -> IO String
pureF String
a = do
String
n <- IO String
queryName
String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
a
pureF' :: IO String
pureF' :: IO String
pureF' = String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"labas"
action :: IO ()
action :: IO ()
action = do
Int -> IO ()
threadDelay Int
10000000
String -> IO ()
putStrLn String
"Hi"
threading :: IO ()
threading :: IO ()
threading = do
IO () -> IO ThreadId
forkIO IO ()
action
IO () -> IO ThreadId
forkIO IO ()
action
String -> IO ()
putStrLn String
"!"
actionC :: Chan String -> IO ()
actionC :: Chan String -> IO ()
actionC Chan String
ch = do
Int -> IO ()
threadDelay Int
10000000
Chan String -> String -> IO ()
forall a. Chan a -> a -> IO ()
writeChan Chan String
ch String
"Hi"
threading' :: IO ()
threading' :: IO ()
threading' = do
Chan String
ch <- IO (Chan String)
forall a. IO (Chan a)
newChan
IO () -> IO ThreadId
forkIO (IO () -> IO ThreadId) -> IO () -> IO ThreadId
forall a b. (a -> b) -> a -> b
$ Chan String -> IO ()
actionC Chan String
ch
IO () -> IO ThreadId
forkIO (IO () -> IO ThreadId) -> IO () -> IO ThreadId
forall a b. (a -> b) -> a -> b
$ Chan String -> IO ()
actionC Chan String
ch
String
v1 <- Chan String -> IO String
forall a. Chan a -> IO a
readChan Chan String
ch
String
v2 <- Chan String -> IO String
forall a. Chan a -> IO a
readChan Chan String
ch
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
v1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
v2
actionA :: String -> IO String
actionA :: String -> IO String
actionA String
v = do
Int -> IO ()
threadDelay Int
5000000
String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
v
threading'' :: IO String
threading'' :: IO String
threading'' = do
Async String
a1 <- IO String -> IO (Async String)
forall a. IO a -> IO (Async a)
async (IO String -> IO (Async String)) -> IO String -> IO (Async String)
forall a b. (a -> b) -> a -> b
$ String -> IO String
actionA String
"First"
Async String
a2 <- IO String -> IO (Async String)
forall a. IO a -> IO (Async a)
async (IO String -> IO (Async String)) -> IO String -> IO (Async String)
forall a b. (a -> b) -> a -> b
$ String -> IO String
actionA String
"Second"
String
v1 <- Async String -> IO String
forall a. Async a -> IO a
wait Async String
a1
String
v2 <- Async String -> IO String
forall a. Async a -> IO a
wait Async String
a2
String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String
v1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
v2
transfer :: TVar Integer -> TVar Integer -> Integer -> STM ()
transfer :: TVar Integer -> TVar Integer -> Integer -> STM ()
transfer TVar Integer
accA TVar Integer
accB Integer
amount = do
Integer
a <- TVar Integer -> STM Integer
forall a. TVar a -> STM a
readTVar TVar Integer
accA
Integer
b <- TVar Integer -> STM Integer
forall a. TVar a -> STM a
readTVar TVar Integer
accB
let newA :: Integer
newA = Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
amount
Bool -> STM () -> STM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
newA Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0) STM ()
forall a. STM a
retry
TVar Integer -> Integer -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar Integer
accA Integer
newA
TVar Integer -> Integer -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar Integer
accB (Integer
b Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
amount)
runTx :: IO ()
runTx :: IO ()
runTx = do
TVar Integer
a <- Integer -> IO (TVar Integer)
forall a. a -> IO (TVar a)
newTVarIO Integer
50
TVar Integer
b <- Integer -> IO (TVar Integer)
forall a. a -> IO (TVar a)
newTVarIO Integer
100
Async ()
z <- IO () -> IO (Async ())
forall a. IO a -> IO (Async a)
async (IO () -> IO (Async ())) -> IO () -> IO (Async ())
forall a b. (a -> b) -> a -> b
$ STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TVar Integer -> TVar Integer -> Integer -> STM ()
transfer TVar Integer
a TVar Integer
b Integer
51
STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TVar Integer -> (Integer -> Integer) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
modifyTVar TVar Integer
a (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
10)
()
_ <- Async () -> IO ()
forall a. Async a -> IO a
wait Async ()
z
Integer
ar <- TVar Integer -> IO Integer
forall a. TVar a -> IO a
readTVarIO TVar Integer
a
Integer
br <- TVar Integer -> IO Integer
forall a. TVar a -> IO a
readTVarIO TVar Integer
b
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"a=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
ar String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", b=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
br