Skip to content

Commit 22dc83f

Browse files
committed
Implements while loops in simple way
1 parent f88dfef commit 22dc83f

File tree

8 files changed

+119
-30
lines changed

8 files changed

+119
-30
lines changed

src/FsToolkit.ErrorHandling/OptionCE.fs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,15 @@ module OptionCE =
7474
[<InlineIfLambda>] generator: unit -> unit option
7575
) : unit option =
7676

77-
let rec whileBuilder () =
78-
if guard () then
79-
this.Bind(this.Run(fun () -> generator ()), (fun () -> this.Run(fun () -> whileBuilder ())))
80-
else
81-
this.Zero()
82-
83-
this.Run(fun () -> whileBuilder ())
77+
let mutable doContinue = true
78+
let mutable result = Some ()
79+
while doContinue && guard () do
80+
match generator () with
81+
| Some () -> ()
82+
| None ->
83+
doContinue <- false
84+
result <- None
85+
result
8486

8587
member inline this.For
8688
(

src/FsToolkit.ErrorHandling/ResultCE.fs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,36 @@ module ResultCE =
7575
[<InlineIfLambda>] generator: unit -> Result<unit, 'error>
7676
) : Result<unit, 'error> =
7777

78-
let rec whileBuilder () =
79-
if guard () then
80-
this.Bind(this.Run(fun () -> generator ()), (fun () -> this.Run(fun () -> whileBuilder ())))
81-
else
82-
this.Zero()
83-
84-
this.Run(fun () -> whileBuilder ())
78+
let mutable doContinue = true
79+
let mutable result = Ok ()
80+
while doContinue && guard () do
81+
match generator () with
82+
| Ok () -> ()
83+
| Error e ->
84+
doContinue <- false
85+
result <- Error e
86+
result
87+
// let rec whileBuilder () =
88+
// if guard () then
89+
// this.Bind(this.Run(fun () -> generator ()), (fun () -> this.Run(fun () -> whileBuilder ())))
90+
// else
91+
// this.Zero()
92+
93+
// this.Run(fun () -> whileBuilder ())
94+
95+
// if guard () then
96+
// let mutable whileBuilder = Unchecked.defaultof<_>
97+
98+
// whileBuilder <-
99+
// fun () ->
100+
// this.Bind(
101+
// this.Run generator,
102+
// (fun () -> if guard () then this.Run whileBuilder else this.Zero())
103+
// )
104+
105+
// this.Run whileBuilder
106+
// else
107+
// this.Zero()
85108

86109

87110
member inline this.For

src/FsToolkit.ErrorHandling/ValidationCE.fs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,15 @@ module ValidationCE =
7474
[<InlineIfLambda>] guard: unit -> bool,
7575
[<InlineIfLambda>] generator: unit -> Validation<unit, 'error>
7676
) : Validation<unit, 'error> =
77-
let rec whileBuilder () =
78-
if guard () then
79-
this.Bind(this.Run(fun () -> generator ()), (fun () -> this.Run(fun () -> whileBuilder ())))
80-
else
81-
this.Zero()
82-
83-
this.Run(fun () -> whileBuilder ())
77+
let mutable doContinue = true
78+
let mutable result = Ok ()
79+
while doContinue && guard () do
80+
match generator () with
81+
| Ok () -> ()
82+
| Error e ->
83+
doContinue <- false
84+
result <- Error e
85+
result
8486

8587
member inline this.For
8688
(

src/FsToolkit.ErrorHandling/ValueOptionCE.fs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,15 @@ module ValueOptionCE =
7373
[<InlineIfLambda>] generator: unit -> _ voption
7474
) : _ voption =
7575

76-
let rec whileBuilder () =
77-
if guard () then
78-
this.Bind(this.Run(fun () -> generator ()), (fun () -> this.Run(fun () -> whileBuilder ())))
79-
else
80-
this.Zero()
81-
82-
this.Run(fun () -> whileBuilder ())
76+
let mutable doContinue = true
77+
let mutable result = ValueSome ()
78+
while doContinue && guard () do
79+
match generator () with
80+
| ValueSome () -> ()
81+
| ValueNone ->
82+
doContinue <- false
83+
result <- ValueNone
84+
result
8385

8486
member inline this.For
8587
(

tests/FsToolkit.ErrorHandling.Tests/OptionCE.fs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,23 @@ let ceTests =
144144
Expect.equal index maxIndex "Index should reach maxIndex"
145145
Expect.equal actual (Some data) "Should be ok"
146146
]
147-
148-
147+
148+
testCase "while bind error" <| fun () ->
149+
let items = [Some 3; Some 4; None]
150+
151+
let mutable index = 0
152+
153+
let actual = option {
154+
while index < items.Length do
155+
let! _ = items[index]
156+
index <- index + 1
157+
158+
return index
159+
}
160+
Expect.equal index (items.Length - 1) "Index should reach maxIndex"
161+
Expect.equal actual (None) "Should be NOPE"
162+
163+
149164
testCase "For in"
150165
<| fun () ->
151166
let data = 42

tests/FsToolkit.ErrorHandling.Tests/ResultCE.fs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,21 @@ let ``ResultCE loop Tests`` =
250250
Expect.equal index (maxIndex) "Index should reach maxIndex"
251251
Expect.equal actual (Ok data) "Should be ok"
252252
]
253+
testCase "while bind error" <| fun () ->
254+
let items = [Ok 3; Ok 4; Error "NOPE"]
255+
256+
let mutable index = 0
257+
258+
let actual = result {
259+
while index < items.Length do
260+
let! _ = items[index]
261+
index <- index + 1
262+
263+
return index
264+
}
265+
Expect.equal index (items.Length - 1) "Index should reach maxIndex"
266+
Expect.equal actual (Error "NOPE") "Should be NOPE"
267+
253268
testCase "for in"
254269
<| fun () ->
255270
let data = 42

tests/FsToolkit.ErrorHandling.Tests/ValidationCE.fs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,20 @@ let ``ValidationCE loop Tests`` =
295295
Expect.equal index maxIndex "Index should reach maxIndex"
296296
Expect.equal actual (Ok data) "Should be ok"
297297
]
298+
testCase "while bind error" <| fun () ->
299+
let items = [Ok 3; Ok 4; Error "NOPE"]
300+
301+
let mutable index = 0
302+
303+
let actual = validation {
304+
while index < items.Length do
305+
let! _ = items[index]
306+
index <- index + 1
307+
308+
return index
309+
}
310+
Expect.equal index (items.Length - 1) "Index should reach maxIndex"
311+
Expect.equal actual (Error ["NOPE"]) "Should be NOPE"
298312
testCase "for in"
299313
<| fun () ->
300314
let data = 42

tests/FsToolkit.ErrorHandling.Tests/ValueOptionCE.fs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,22 @@ let ceTests =
147147
Expect.equal index maxIndex "Index should reach maxIndex"
148148
Expect.equal actual (ValueSome data) "Should be ok"
149149
]
150+
151+
testCase "while bind error" <| fun () ->
152+
let items = [ValueSome 3; ValueSome 4; ValueNone]
153+
154+
let mutable index = 0
155+
156+
let actual = voption {
157+
while index < items.Length do
158+
let! _ = items[index]
159+
index <- index + 1
160+
161+
return index
162+
}
163+
Expect.equal index (items.Length - 1) "Index should reach maxIndex"
164+
Expect.equal actual (ValueNone) "Should be NOPE"
165+
150166
testCase "For in"
151167
<| fun () ->
152168
let data = 42

0 commit comments

Comments
 (0)