In Chapter 12 Lexer and parser generators, I fail to compile the following example :
{
type token = EOL | INT of int | PLUS
module Make (M : sig
type 'a t
val return: 'a -> 'a t
val bind: 'a t -> ('a -> 'b t) -> 'b t
val fail : string -> 'a t
(* Set up lexbuf *)
val on_refill : Lexing.lexbuf -> unit t
end)
= struct
let refill_handler k lexbuf arg =
M.bind (M.on_refill lexbuf) (fun () -> k lexbuf arg)
}
refill {refill_handler}
rule token = parse
| [' ' '\t']
{ token lexbuf }
| '\n'
{ M.return EOL }
| ['0'-'9']+ as i
{ M.return (INT (int_of_string i)) }
| '+'
{ M.return PLUS }
| _
{ M.fail "unexpected character" }
{
end
}
I also do not understand how the module Make is working, and where it comes from. Note : I am currently using 4.02.1 ocaml compiler.
This code defines the module Make, which is a functor. That is, it takes a module as a parameter and returns a module.
The module parameter that it accepts is an arbitrary monad, which in essence is a way of saying what happens when you do something followed by something else.
You can find a description of monads here: http://blog.enfranchisedmind.com/2007/08/a-monad-tutorial-for-ocaml
I got the code to compile by changing the refill function to this:
let refill_handler k lexbuf =
M.bind (M.on_refill lexbuf) (fun () -> k lexbuf)
The original definition doesn't seem to match the type of a refill handler. (But I could be missing something; this kind of code takes a lot of getting used to.)