2

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.

4

1 に答える 1

2

このコードは、ファンクターであるモジュール Make を定義します。つまり、モジュールをパラメーターとして取り、モジュールを返します。

受け入れるモジュールパラメータは任意のモナドであり、本質的には、何かを実行した後に別のことを実行したときに何が起こるかを示す方法です。

ここでモナドの説明を見つけることができます: http://blog.enfranchisedmind.com/2007/08/a-monad-tutorial-for-ocaml

refill 関数を次のように変更して、コンパイルするコードを取得しました。

let refill_handler k lexbuf =
    M.bind (M.on_refill lexbuf) (fun () -> k lexbuf)

元の定義は、refill ハンドラーの型と一致していないようです。(しかし、何かが欠けている可能性があります。この種のコードには慣れるまでに時間がかかります。)

于 2016-01-29T07:04:11.050 に答える