I like exploring ideas and new libraries using the REPL (Read Evaluate Print Loop). There’s something about being able to get started quickly without having to plan out an entire project. I started looking at parser combinators. It’s been on my “to learn” list for some time now. I started with FParsec for .Net and hit a couple of snags getting things running with F# Interactive. The FParsec documentation has the solutions to these issues but I thought I would put them here so I can remember.
Library Load Order Matters
FParsec uses 2 libraries, FParsecCS.dll and FParsec.dll. Loading them up in FSI should be fairly straight forward, except you must load them up in the correct order.
#r "FParsecCS.dll"
#r "FParsec.dll"
Failing to do so and you will be greeted with a message similar to this:
error FS0074: The type referenced through’FParsec.CharStream`1’ is defined in an assembly that is not referenced.
Source: FParsec Tutorial – Two DLLs
"If you reference the DLLs in the F# Interactive console, you need to reference FParsecCS.dll before you reference FParsec.dll."
Value Restriction
A value restriction occurs when the Type Inference determines the type to be too generic. When working with the REPL the first thing to do is add type annotations. With FParsec, the recommended way to alleviate the value restriction is to add a type alias and use it in the type annotation. I wasn’t using any State
while learning to parse the text. I created a type alias for unit
and added it to the type annotation. My code looked like below.
type NodeState = unit
let pname : Parser<string, NodeState> = manyChars asciiLetter .>> spaces
Source: FParsec Tutorial – Value Restriction
Summary
I hit two small hurdles when using FParsec with the REPL. The load order of the two FParsec libraries matter. The other hurdle was a value restriction in which I created a type alias to annotate the parsing state for the combinators. After dealing with the library load order and value restriction, I was on to learning FParsec in F# interactive.