|
1 | 1 | module Examples where
|
2 |
| - import Control.Monad.Eff.Console (CONSOLE()) |
3 |
| - |
4 |
| - import Data.Either(either) |
5 |
| - |
6 |
| - import Prelude |
7 |
| - import Control.Monad.Aff |
8 |
| - import Control.Monad.Aff.AVar |
9 |
| - import Control.Monad.Aff.Par |
10 |
| - import Control.Monad.Aff.Console(print) |
11 |
| - import Control.Apply((*>)) |
12 |
| - import Control.Alt(Alt, (<|>)) |
13 |
| - import Control.Monad.Eff.Class(liftEff) |
14 |
| - import Control.Monad.Eff.Exception(error) |
15 |
| - import Control.Monad.Error.Class(throwError) |
16 |
| - |
17 |
| - type Test a = forall e. Aff (console :: CONSOLE | e) a |
18 |
| - type TestAVar a = forall e. Aff (console :: CONSOLE, avar :: AVAR | e) a |
19 |
| - |
20 |
| - test_sequencing :: Int -> Test String |
21 |
| - test_sequencing 0 = print "Done" |
22 |
| - test_sequencing n = do |
23 |
| - later' 100 (print (show (n / 10) ++ " seconds left")) |
24 |
| - test_sequencing (n - 1) |
25 |
| - |
26 |
| - test_pure :: Test String |
27 |
| - test_pure = do |
28 |
| - pure unit |
29 |
| - pure unit |
30 |
| - pure unit |
31 |
| - print "Success: Got all the way past 4 pures" |
32 |
| - |
33 |
| - test_attempt :: Test String |
34 |
| - test_attempt = do |
35 |
| - e <- attempt (throwError (error "Oh noes!")) |
36 |
| - either (const $ print "Success: Exception caught") (const $ print "Failure: Exception NOT caught!!!") e |
37 |
| - |
38 |
| - test_apathize :: Test String |
39 |
| - test_apathize = do |
40 |
| - apathize $ throwError (error "Oh noes!") |
41 |
| - print "Success: Exceptions don't stop the apathetic" |
42 |
| - |
43 |
| - test_putTakeVar :: TestAVar String |
44 |
| - test_putTakeVar = do |
45 |
| - v <- makeVar |
46 |
| - forkAff (later $ putVar v 1.0) |
47 |
| - a <- takeVar v |
48 |
| - print ("Success: Value " ++ show a) |
49 |
| - |
50 |
| - test_killFirstForked :: Test String |
51 |
| - test_killFirstForked = do |
52 |
| - c <- forkAff (later' 100 $ pure "Failure: This should have been killed!") |
53 |
| - b <- c `cancel` (error "Just die") |
54 |
| - print (if b then "Success: Killed first forked" else "Failure: Couldn't kill first forked") |
55 |
| - |
56 |
| - |
57 |
| - test_killVar :: TestAVar String |
58 |
| - test_killVar = do |
59 |
| - v <- makeVar |
60 |
| - killVar v (error "DOA") |
61 |
| - e <- attempt $ takeVar v |
62 |
| - either (const $ print "Success: Killed queue dead") (const $ print "Failure: Oh noes, queue survived!") e |
63 |
| - |
64 |
| - test_finally :: TestAVar String |
65 |
| - test_finally = do |
66 |
| - v <- makeVar |
67 |
| - finally |
68 |
| - (putVar v 0) |
69 |
| - (putVar v 2) |
70 |
| - apathize $ finally |
71 |
| - (throwError (error "poof!") *> putVar v 666) -- this putVar should not get executed |
72 |
| - (putVar v 40) |
73 |
| - n1 <- takeVar v |
74 |
| - n2 <- takeVar v |
75 |
| - n3 <- takeVar v |
76 |
| - print $ if n1 + n2 + n3 == 42 then "Success: effects amount to 42." |
77 |
| - else "Failure: Expected 42." |
78 |
| - |
79 |
| - test_parRace :: TestAVar String |
80 |
| - test_parRace = do |
81 |
| - s <- runPar (Par (later' 100 $ pure "Success: Early bird got the worm") <|> |
82 |
| - Par (later' 200 $ pure "Failure: Late bird got the worm")) |
83 |
| - print s |
84 |
| - |
85 |
| - test_parRaceKill1 :: TestAVar String |
86 |
| - test_parRaceKill1 = do |
87 |
| - s <- runPar (Par (later' 100 $ throwError (error ("Oh noes!"))) <|> |
88 |
| - Par (later' 200 $ pure "Success: Early error was ignored in favor of late success")) |
89 |
| - print s |
90 |
| - |
91 |
| - test_parRaceKill2 :: TestAVar String |
92 |
| - test_parRaceKill2 = do |
93 |
| - e <- attempt $ runPar (Par (later' 100 $ throwError (error ("Oh noes!"))) <|> |
94 |
| - Par (later' 200 $ throwError (error ("Oh noes!")))) |
95 |
| - either (const $ print "Success: Killing both kills it dead") (const $ print "Failure: It's alive!!!") e |
96 |
| - |
97 |
| - test_semigroupCanceler :: Test String |
98 |
| - test_semigroupCanceler = |
99 |
| - let |
100 |
| - c = Canceler (const (pure true)) <> Canceler (const (pure true)) |
101 |
| - in do |
102 |
| - v <- cancel c (error "CANCEL") |
103 |
| - print (if v then "Success: Canceled semigroup composite canceler" |
104 |
| - else "Failure: Could not cancel semigroup composite canceler") |
105 |
| - |
106 |
| - test_cancelLater :: TestAVar String |
107 |
| - test_cancelLater = do |
108 |
| - c <- forkAff $ (do pure "Binding" |
109 |
| - _ <- later' 100 $ print ("Failure: Later was not canceled!") |
110 |
| - pure "Binding") |
111 |
| - v <- cancel c (error "Cause") |
112 |
| - print (if v then "Success: Canceled later" else "Failure: Did not cancel later") |
113 |
| - |
114 |
| - test_cancelPar :: TestAVar String |
115 |
| - test_cancelPar = do |
116 |
| - c <- forkAff <<< runPar $ Par (later' 100 $ print "Failure: #1 should not get through") <|> |
117 |
| - Par (later' 100 $ print "Failure: #2 should not get through") |
118 |
| - v <- c `cancel` (error "Must cancel") |
119 |
| - print (if v then "Success: Canceling composite of two Par succeeded" |
120 |
| - else "Failure: Canceling composite of two Par failed") |
121 |
| - |
122 |
| - main = launchAff $ do |
123 |
| - print "Testing sequencing" |
124 |
| - test_sequencing 3 |
125 |
| - |
126 |
| - print "Testing pure" |
127 |
| - test_pure |
128 |
| - |
129 |
| - print "Testing attempt" |
130 |
| - test_attempt |
131 |
| - |
132 |
| - print "Testing later" |
133 |
| - later $ print "Success: It happened later" |
134 |
| - |
135 |
| - print "Testing kill of later" |
136 |
| - test_cancelLater |
137 |
| - |
138 |
| - print "Testing kill of first forked" |
139 |
| - test_killFirstForked |
140 |
| - |
141 |
| - print "Testing apathize" |
142 |
| - test_apathize |
143 |
| - |
144 |
| - print "Testing semigroup canceler" |
145 |
| - test_semigroupCanceler |
146 |
| - |
147 |
| - print "Testing AVar - putVar, takeVar" |
148 |
| - test_putTakeVar |
149 |
| - |
150 |
| - print "Testing AVar killVar" |
151 |
| - test_killVar |
152 |
| - |
153 |
| - print "Testing finally" |
154 |
| - test_finally |
155 |
| - |
156 |
| - print "Testing Par (<|>)" |
157 |
| - test_parRace |
158 |
| - |
159 |
| - print "Testing Par (<|>) - kill one" |
160 |
| - test_parRaceKill1 |
161 |
| - |
162 |
| - print "Testing Par (<|>) - kill two" |
163 |
| - test_parRaceKill2 |
164 |
| - |
165 |
| - print "Testing cancel of Par (<|>)" |
166 |
| - test_cancelPar |
167 |
| - |
168 |
| - print "Done testing" |
| 2 | + |
| 3 | +import Prelude |
| 4 | + |
| 5 | +import Control.Monad.Aff |
| 6 | +import Control.Monad.Aff.AVar |
| 7 | +import Control.Monad.Aff.Par |
| 8 | +import Control.Monad.Aff.Console (print) |
| 9 | +import Control.Apply ((*>)) |
| 10 | +import Control.Alt (Alt, (<|>)) |
| 11 | +import Control.Monad.Eff (Eff()) |
| 12 | +import Control.Monad.Eff.Console (CONSOLE()) |
| 13 | +import Control.Monad.Eff.Exception (EXCEPTION(), error) |
| 14 | +import Control.Monad.Error.Class (throwError) |
| 15 | +import Data.Either (either) |
| 16 | + |
| 17 | +type Test a = forall e. Aff (console :: CONSOLE | e) a |
| 18 | +type TestAVar a = forall e. Aff (console :: CONSOLE, avar :: AVAR | e) a |
| 19 | + |
| 20 | +test_sequencing :: Int -> Test Unit |
| 21 | +test_sequencing 0 = print "Done" |
| 22 | +test_sequencing n = do |
| 23 | + later' 100 (print (show (n / 10) ++ " seconds left")) |
| 24 | + test_sequencing (n - 1) |
| 25 | + |
| 26 | +test_pure :: Test Unit |
| 27 | +test_pure = do |
| 28 | + pure unit |
| 29 | + pure unit |
| 30 | + pure unit |
| 31 | + print "Success: Got all the way past 4 pures" |
| 32 | + |
| 33 | +test_attempt :: Test Unit |
| 34 | +test_attempt = do |
| 35 | + e <- attempt (throwError (error "Oh noes!")) |
| 36 | + either (const $ print "Success: Exception caught") (const $ print "Failure: Exception NOT caught!!!") e |
| 37 | + |
| 38 | +test_apathize :: Test Unit |
| 39 | +test_apathize = do |
| 40 | + apathize $ throwError (error "Oh noes!") |
| 41 | + print "Success: Exceptions don't stop the apathetic" |
| 42 | + |
| 43 | +test_putTakeVar :: TestAVar Unit |
| 44 | +test_putTakeVar = do |
| 45 | + v <- makeVar |
| 46 | + forkAff (later $ putVar v 1.0) |
| 47 | + a <- takeVar v |
| 48 | + print ("Success: Value " ++ show a) |
| 49 | + |
| 50 | +test_killFirstForked :: Test Unit |
| 51 | +test_killFirstForked = do |
| 52 | + c <- forkAff (later' 100 $ pure "Failure: This should have been killed!") |
| 53 | + b <- c `cancel` (error "Just die") |
| 54 | + print (if b then "Success: Killed first forked" else "Failure: Couldn't kill first forked") |
| 55 | + |
| 56 | + |
| 57 | +test_killVar :: TestAVar Unit |
| 58 | +test_killVar = do |
| 59 | + v <- makeVar |
| 60 | + killVar v (error "DOA") |
| 61 | + e <- attempt $ takeVar v |
| 62 | + either (const $ print "Success: Killed queue dead") (const $ print "Failure: Oh noes, queue survived!") e |
| 63 | + |
| 64 | +test_finally :: TestAVar Unit |
| 65 | +test_finally = do |
| 66 | + v <- makeVar |
| 67 | + finally |
| 68 | + (putVar v 0) |
| 69 | + (putVar v 2) |
| 70 | + apathize $ finally |
| 71 | + (throwError (error "poof!") *> putVar v 666) -- this putVar should not get executed |
| 72 | + (putVar v 40) |
| 73 | + n1 <- takeVar v |
| 74 | + n2 <- takeVar v |
| 75 | + n3 <- takeVar v |
| 76 | + print $ if n1 + n2 + n3 == 42 then "Success: effects amount to 42." |
| 77 | + else "Failure: Expected 42." |
| 78 | + |
| 79 | +test_parRace :: TestAVar Unit |
| 80 | +test_parRace = do |
| 81 | + s <- runPar (Par (later' 100 $ pure "Success: Early bird got the worm") <|> |
| 82 | + Par (later' 200 $ pure "Failure: Late bird got the worm")) |
| 83 | + print s |
| 84 | + |
| 85 | +test_parRaceKill1 :: TestAVar Unit |
| 86 | +test_parRaceKill1 = do |
| 87 | + s <- runPar (Par (later' 100 $ throwError (error ("Oh noes!"))) <|> |
| 88 | + Par (later' 200 $ pure "Success: Early error was ignored in favor of late success")) |
| 89 | + print s |
| 90 | + |
| 91 | +test_parRaceKill2 :: TestAVar Unit |
| 92 | +test_parRaceKill2 = do |
| 93 | + e <- attempt $ runPar (Par (later' 100 $ throwError (error ("Oh noes!"))) <|> |
| 94 | + Par (later' 200 $ throwError (error ("Oh noes!")))) |
| 95 | + either (const $ print "Success: Killing both kills it dead") (const $ print "Failure: It's alive!!!") e |
| 96 | + |
| 97 | +test_semigroupCanceler :: Test Unit |
| 98 | +test_semigroupCanceler = |
| 99 | + let |
| 100 | + c = Canceler (const (pure true)) <> Canceler (const (pure true)) |
| 101 | + in do |
| 102 | + v <- cancel c (error "CANCEL") |
| 103 | + print (if v then "Success: Canceled semigroup composite canceler" |
| 104 | + else "Failure: Could not cancel semigroup composite canceler") |
| 105 | + |
| 106 | +test_cancelLater :: TestAVar Unit |
| 107 | +test_cancelLater = do |
| 108 | + c <- forkAff $ (do pure "Binding" |
| 109 | + _ <- later' 100 $ print ("Failure: Later was not canceled!") |
| 110 | + pure "Binding") |
| 111 | + v <- cancel c (error "Cause") |
| 112 | + print (if v then "Success: Canceled later" else "Failure: Did not cancel later") |
| 113 | + |
| 114 | +test_cancelPar :: TestAVar Unit |
| 115 | +test_cancelPar = do |
| 116 | + c <- forkAff <<< runPar $ Par (later' 100 $ print "Failure: #1 should not get through") <|> |
| 117 | + Par (later' 100 $ print "Failure: #2 should not get through") |
| 118 | + v <- c `cancel` (error "Must cancel") |
| 119 | + print (if v then "Success: Canceling composite of two Par succeeded" |
| 120 | + else "Failure: Canceling composite of two Par failed") |
| 121 | + |
| 122 | +main :: forall eff . Eff ( avar :: AVAR, console :: CONSOLE, err :: EXCEPTION | eff ) Unit |
| 123 | +main = launchAff $ do |
| 124 | + print "Testing sequencing" |
| 125 | + test_sequencing 3 |
| 126 | + |
| 127 | + print "Testing pure" |
| 128 | + test_pure |
| 129 | + |
| 130 | + print "Testing attempt" |
| 131 | + test_attempt |
| 132 | + |
| 133 | + print "Testing later" |
| 134 | + later $ print "Success: It happened later" |
| 135 | + |
| 136 | + print "Testing kill of later" |
| 137 | + test_cancelLater |
| 138 | + |
| 139 | + print "Testing kill of first forked" |
| 140 | + test_killFirstForked |
| 141 | + |
| 142 | + print "Testing apathize" |
| 143 | + test_apathize |
| 144 | + |
| 145 | + print "Testing semigroup canceler" |
| 146 | + test_semigroupCanceler |
| 147 | + |
| 148 | + print "Testing AVar - putVar, takeVar" |
| 149 | + test_putTakeVar |
| 150 | + |
| 151 | + print "Testing AVar killVar" |
| 152 | + test_killVar |
| 153 | + |
| 154 | + print "Testing finally" |
| 155 | + test_finally |
| 156 | + |
| 157 | + print "Testing Par (<|>)" |
| 158 | + test_parRace |
| 159 | + |
| 160 | + print "Testing Par (<|>) - kill one" |
| 161 | + test_parRaceKill1 |
| 162 | + |
| 163 | + print "Testing Par (<|>) - kill two" |
| 164 | + test_parRaceKill2 |
| 165 | + |
| 166 | + print "Testing cancel of Par (<|>)" |
| 167 | + test_cancelPar |
| 168 | + |
| 169 | + print "Done testing" |
0 commit comments