@@ -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