Skip to content

Commit 64706fd

Browse files
Fixed loops in the maybe computation expression that would only iterate once and then return None for the rest of the expression.
1 parent 0af75e9 commit 64706fd

2 files changed

Lines changed: 27 additions & 2 deletions

File tree

src/FSharpx.Extras/ComputationExpressions/Monad.fs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,9 @@ module Option =
116116
this.TryFinally(body res, fun () -> match res with null -> () | disp -> disp.Dispose())
117117

118118
member this.While(guard, f) =
119-
if not (guard()) then this.Zero() else
120-
this.Bind(f(), fun _ -> this.While(guard, f))
119+
if not (guard()) then Some () else
120+
do f() |> ignore
121+
this.While(guard, f)
121122

122123
member this.For(sequence:seq<_>, body) =
123124
this.Using(sequence.GetEnumerator(),

tests/FSharpx.Tests/MaybeTest.fs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,27 @@ let ``monadplus laws``() =
8080
fun a b -> mplus (ret a) b = ret a
8181
// fsCheck "left distribution" <|
8282
// fun a b f -> (mplus a b >>= f) = (mplus (a >>= f) (b >>= f))
83+
84+
[<Test>]
85+
let ``for loops enumerate entire sequence and subsequent expressions also run``() =
86+
let count = ref 0
87+
let result = maybe {
88+
for i in [1;2;3] do
89+
incr count
90+
return true
91+
}
92+
93+
!count |> should equal 3
94+
result |> should equal (Some true)
95+
96+
[<Test>]
97+
let ``while loops execute until guard is false and subsequent expressions also run``() =
98+
let count = ref 0
99+
let result = maybe {
100+
while !count < 3 do
101+
incr count
102+
return true
103+
}
104+
105+
!count |> should equal 3
106+
result |> should equal (Some true)

0 commit comments

Comments
 (0)