@@ -4,7 +4,8 @@ namespace ZMidi.Internal
44module ParserMonad =
55
66 open System.IO
7-
7+ open FSharpPlus
8+ open FSharpPlus.Data
89 open ZMidi.Internal .Utils
910
1011 /// Status is either OFF or the previous VoiceEvent * Channel.
@@ -85,8 +86,7 @@ module ParserMonad =
8586 #endif
8687 )
8788
88- type ParserMonad < 'a > =
89- ParserMonad of ( MidiData -> State -> Result < 'a * State , ParseError > )
89+ type ParserMonad < 'a > = ReaderT< MidiData, StateT< State, Result< 'a * State, ParseError>>>
9090
9191 let nullOut = new StreamWriter( Stream.Null) :> TextWriter
9292 let mutable debug = false
@@ -100,7 +100,7 @@ module ParserMonad =
100100 let inline private apply1 ( parser : ParserMonad < 'a >)
101101 ( midiData : byte [])
102102 ( state : State ) : Result < 'a * State , ParseError > =
103- let ( ParserMonad fn ) = parser
103+ let fn = ReaderT.run parser >> StateT.run
104104 try
105105 let result = fn midiData state
106106 let oldState = state
@@ -129,8 +129,9 @@ module ParserMonad =
129129 )
130130 )
131131
132+ let ParserMonad f = ReaderT ( fun r -> StateT ( fun s -> f r s))
132133 let inline mreturn ( x : 'a ) : ParserMonad < 'a > =
133- ParserMonad <| fun _ st -> Ok ( x, st)
134+ ReaderT <| fun _ -> StateT ( fun st -> Ok ( x, st) )
134135
135136 let inline private bindM ( parser : ParserMonad < 'a >)
136137 ( next : 'a -> ParserMonad < 'b >) : ParserMonad < 'b > =
@@ -156,31 +157,8 @@ module ParserMonad =
156157
157158 let (>>= ) ( m: ParserMonad< 'a>) ( k: 'a -> ParserMonad< 'b>) : ParserMonad< 'b> =
158159 bindM m k
159-
160- type ParserBuilder () =
161- member inline self.ReturnFrom ( ma : ParserMonad < 'a >) : ParserMonad < 'a > = ma
162- member inline self.Return x = mreturn x
163- member inline self.Bind ( p , f ) = bindM p f
164- member inline self.Zero a = ParserMonad ( fun input state -> Ok( a, state))
165- //member self.Combine (ma, mb) = ma >>= mb
166-
167- // inspired from http://www.fssnip.net/7UJ/title/ResultBuilder-Computational-Expression
168- // probably broken
169- member inline self.TryFinally ( m , compensation ) =
170- try self.ReturnFrom( m)
171- finally compensation()
172-
173- //member self.Delay(f: unit -> ParserMonad<'a>) : ParserMonad<'a> = f ()
174- //member self.Using(res:#System.IDisposable, body) =
175- // self.TryFinally(body res, fun () -> if not (isNull res) then res.Dispose())
176- //member self.While(guard, f) =
177- // if not (guard()) then self.Zero () else
178- // do f() |> ignore
179- // self.While(guard, f)
180- //member self.For(sequence:seq<_>, body) =
181- // self.Using(sequence.GetEnumerator(), fun enum -> self.While(enum.MoveNext, fun () -> self.Delay(fun () -> body enum.Current)))
182-
183- let ( parseMidi : ParserBuilder ) = new ParserBuilder()
160+
161+ let parseMidi = monad
184162
185163 let runParser ( ma : ParserMonad < 'a >) input initialState =
186164 apply1 ma input initialState
@@ -409,7 +387,7 @@ module ParserMonad =
409387 <??> sprintf " word14be: failed at %i "
410388
411389 /// Parse a word32 (big endian).
412- let readUInt32be =
390+ let readUInt32be : ParserMonad < _ > =
413391 parseMidi {
414392 let! a = readByte
415393 let! b = readByte
@@ -419,7 +397,7 @@ module ParserMonad =
419397 }
420398
421399 /// Parse a word24 (big endian).
422- let readWord24be =
400+ let readWord24be : ParserMonad < _ > =
423401 parseMidi {
424402 let! a = readByte
425403 let! b = readByte
0 commit comments