@@ -4,7 +4,8 @@ namespace ZMidi.Internal
4
4
module ParserMonad =
5
5
6
6
open System.IO
7
-
7
+ open FSharpPlus
8
+ open FSharpPlus.Data
8
9
open ZMidi.Internal .Utils
9
10
10
11
/// Status is either OFF or the previous VoiceEvent * Channel.
@@ -85,8 +86,7 @@ module ParserMonad =
85
86
#endif
86
87
)
87
88
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>>>
90
90
91
91
let nullOut = new StreamWriter( Stream.Null) :> TextWriter
92
92
let mutable debug = false
@@ -100,7 +100,7 @@ module ParserMonad =
100
100
let inline private apply1 ( parser : ParserMonad < 'a >)
101
101
( midiData : byte [])
102
102
( state : State ) : Result < 'a * State , ParseError > =
103
- let ( ParserMonad fn ) = parser
103
+ let fn = ReaderT.run parser >> StateT.run
104
104
try
105
105
let result = fn midiData state
106
106
let oldState = state
@@ -129,8 +129,9 @@ module ParserMonad =
129
129
)
130
130
)
131
131
132
+ let ParserMonad f = ReaderT ( fun r -> StateT ( fun s -> f r s))
132
133
let inline mreturn ( x : 'a ) : ParserMonad < 'a > =
133
- ParserMonad <| fun _ st -> Ok ( x, st)
134
+ ReaderT <| fun _ -> StateT ( fun st -> Ok ( x, st) )
134
135
135
136
let inline private bindM ( parser : ParserMonad < 'a >)
136
137
( next : 'a -> ParserMonad < 'b >) : ParserMonad < 'b > =
@@ -156,31 +157,8 @@ module ParserMonad =
156
157
157
158
let (>>= ) ( m: ParserMonad< 'a>) ( k: 'a -> ParserMonad< 'b>) : ParserMonad< 'b> =
158
159
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
184
162
185
163
let runParser ( ma : ParserMonad < 'a >) input initialState =
186
164
apply1 ma input initialState
@@ -385,7 +363,7 @@ module ParserMonad =
385
363
<??> sprintf " word14be: failed at %i "
386
364
387
365
/// Parse a word32 (big endian).
388
- let readUInt32be =
366
+ let readUInt32be : ParserMonad < _ > =
389
367
parseMidi {
390
368
let! a = readByte
391
369
let! b = readByte
@@ -395,7 +373,7 @@ module ParserMonad =
395
373
}
396
374
397
375
/// Parse a word24 (big endian).
398
- let readWord24be =
376
+ let readWord24be : ParserMonad < _ > =
399
377
parseMidi {
400
378
let! a = readByte
401
379
let! b = readByte
0 commit comments