@@ -170,6 +170,51 @@ module ComputationExpressions =
170
170
171
171
()
172
172
173
+ module Applicative =
174
+ [<Test>]
175
+ let applicateiveShortCircuits () =
176
+
177
+ // This should be the case for any lazy monad stack with short-circuit applicative (Collections, Options, short-circuits Eithers)
178
+
179
+ let mutable actions : string list = []
180
+
181
+ let getNumberO i : SeqT < Task < _ >, int > = monad.plus {
182
+ let! _ =
183
+ monad' {
184
+ do ! Task.Delay 10 |> Task.ignore
185
+ actions <- " init" :: actions
186
+ }
187
+ |> SeqT.lift
188
+
189
+ let! x =
190
+ monad' {
191
+ do ! Task.Delay 10 |> Task.ignore
192
+ actions <- ( " read " + ( string i)) :: actions
193
+ return ( string i)
194
+ }
195
+ |>> tryParse
196
+ |>> Option.toList
197
+ |>> List.toSeq
198
+ |> SeqT
199
+ if x = i + 10 then yield x // will be always false
200
+ }
201
+
202
+ let seqt = result (+) <*> getNumberO 1 <*> getNumberO 2
203
+
204
+ // Non-lazy stacks would have been executed at this point
205
+ CollectionAssert.AreEqual ( actions, [])
206
+
207
+ let res = SeqT.run seqt
208
+
209
+ // Still executing
210
+ CollectionAssert.AreEqual ( actions, [])
211
+
212
+ // Now we block until it finish
213
+ CollectionAssert.AreEqual ( res.Result, [])
214
+
215
+ // Since the first value was an empty list, no further effect should be expected
216
+ CollectionAssert.AreEqual ( actions, [ " read 1" ; " init" ])
217
+
173
218
174
219
module AsyncSeq =
175
220
@@ -280,4 +325,4 @@ module ComputationExpressions =
280
325
let expected = Seq.zip la lb |> Seq.map ((<||) (+)) |> SeqT.ofSeq
281
326
Assert.True ( EQ expected actual)
282
327
283
-
328
+
0 commit comments