Skip to content

Commit 329cf5c

Browse files
fix boundRepeat (doh!)
1 parent 60755d0 commit 329cf5c

File tree

1 file changed

+26
-19
lines changed

1 file changed

+26
-19
lines changed

src/ZMidi/Internal/ParserMonad.fs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -136,28 +136,31 @@ module ParserMonad =
136136
let inline mfor (items: #seq<'a>) (fn: 'a -> ParserMonad<'b>) : ParserMonad<seq<'b>> = failwithf ""
137137

138138

139+
let (>>=) (m: ParserMonad<'a>) (k: 'a -> ParserMonad<'b>) : ParserMonad<'b> =
140+
bindM m k
141+
139142
type ParserBuilder() =
140143
member self.ReturnFrom (ma:ParserMonad<'a>) : ParserMonad<'a> = ma
141144
member self.Return x = mreturn x
142145
member self.Bind (p,f) = bindM p f
143-
member self.Zero () = mzero ()
144-
member self.Combine (ma, mb) = mplus ma mb
146+
member self.Zero a = ParserMonad (fun input state -> Ok(a, state))
147+
//member self.Combine (ma, mb) = ma >>= mb
145148

146149
// inspired from http://www.fssnip.net/7UJ/title/ResultBuilder-Computational-Expression
147150
// probably broken
148151
member self.TryFinally(m, compensation) =
149152
try self.ReturnFrom(m)
150153
finally compensation()
151154

152-
member self.Delay(f: unit -> ParserMonad<'a>) : ParserMonad<'a> = delayM f
153-
member self.Using(res:#System.IDisposable, body) =
154-
self.TryFinally(body res, fun () -> match res with null -> () | disp -> disp.Dispose())
155-
member self.While(guard, f) =
156-
if not (guard()) then self.Zero() else
157-
do f() |> ignore
158-
self.While(guard, f)
159-
member self.For(sequence:seq<_>, body) =
160-
self.Using(sequence.GetEnumerator(), fun enum -> self.While(enum.MoveNext, fun () -> self.Delay(fun () -> body enum.Current)))
155+
//member self.Delay(f: unit -> ParserMonad<'a>) : ParserMonad<'a> = f ()
156+
//member self.Using(res:#System.IDisposable, body) =
157+
// self.TryFinally(body res, fun () -> if not (isNull res) then res.Dispose())
158+
//member self.While(guard, f) =
159+
// if not (guard()) then self.Zero () else
160+
// do f() |> ignore
161+
// self.While(guard, f)
162+
//member self.For(sequence:seq<_>, body) =
163+
// self.Using(sequence.GetEnumerator(), fun enum -> self.While(enum.MoveNext, fun () -> self.Delay(fun () -> body enum.Current)))
161164

162165
let (parseMidi:ParserBuilder) = new ParserBuilder()
163166

@@ -181,9 +184,6 @@ module ParserMonad =
181184
| Ok result -> Ok result
182185
| Error _ -> Error(mkOtherParseError st genMessage)
183186

184-
let (>>=) (m: ParserMonad<'a>) (k: 'a -> ParserMonad<'b>) : ParserMonad<'b> =
185-
bindM m k
186-
187187
///
188188
let fmap (f: 'a -> 'b) (p: ParserMonad<'a>) : ParserMonad<'b> =
189189
parseMidi {
@@ -284,12 +284,19 @@ module ParserMonad =
284284

285285
/// Run a parser within a bounded section of the input stream.
286286
let inline boundRepeat (n: ^T) (p: ParserMonad<'a>) : ParserMonad<'a array> =
287+
288+
289+
let rec loop i (data: 'a array) =
290+
parseMidi {
291+
if i < n then
292+
let! r = p
293+
data.[int i] <- r
294+
return! (loop (i + LanguagePrimitives.GenericOne) data)
295+
}
287296
parseMidi {
288-
let l = Array.zeroCreate (int n) // can't use array expression inside a CE (at least as is)
289-
for (i: 'T) in LanguagePrimitives.GenericZero<'T> .. (n - LanguagePrimitives.GenericOne<'T>) do
290-
let! r = p
291-
l.[int i] <- r
292-
return l
297+
let data = Array.zeroCreate (int n) // can't use array expression inside a CE (at least as is)
298+
do! loop LanguagePrimitives.GenericZero data
299+
return data
293300
}
294301

295302
/// Apply the parser for /count/ times, derive the final answer

0 commit comments

Comments
 (0)