Search code examples
ocamlocamllex

Ocamllex refill-handler example


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.


Solution

  • 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.)