Skip to content

Commit 19ddde9

Browse files
committed
Switch to ReaderT
1 parent c5a22cb commit 19ddde9

File tree

2 files changed

+11
-33
lines changed

2 files changed

+11
-33
lines changed

src/ZMidi/Internal/ParserMonad.fs

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ namespace ZMidi.Internal
44
module 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
@@ -385,7 +363,7 @@ module ParserMonad =
385363
<??> sprintf "word14be: failed at %i"
386364

387365
/// Parse a word32 (big endian).
388-
let readUInt32be =
366+
let readUInt32be : ParserMonad<_> =
389367
parseMidi {
390368
let! a = readByte
391369
let! b = readByte
@@ -395,7 +373,7 @@ module ParserMonad =
395373
}
396374

397375
/// Parse a word24 (big endian).
398-
let readWord24be =
376+
let readWord24be : ParserMonad<_> =
399377
parseMidi {
400378
let! a = readByte
401379
let! b = readByte

src/ZMidi/Read.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ module ReadFile =
186186
|> function | Some i -> true
187187
| None -> false
188188

189-
let rec sysExContPackets =
189+
let rec sysExContPackets : ParserMonad<_> =
190190
parseMidi {
191191
let! d = deltaTime
192192
let! b = getVarlenBytes

0 commit comments

Comments
 (0)