0

有人可以帮我解释为什么我在这一行有语法错误:let wordMap = StringMap.empty?这包含在 .mll 文件中。模块 StringMap 在上面定义。

let lexbuf = Lexing.from_channel stdin in
    let wordlist =
        let rec next l = match token lexbuf with
            EOF -> l
            | Word(s) -> next (s :: l)
        in next []

    let wordMap = StringMap.empty in 
        let wcList  = StringMap.fold (fun word count l -> (string_of_int count ^ " " ^ word) :: l) wordMap [] in 

        List.iter print_endline wcList;;

我知道它什么也没打印,这只是为了测试。

4

3 回答 3

2

像这样的声明:

let v = expr

只能出现在模块的最外层。这是声明模块全局名称的方法。

wordlist但是您在表达式中有这样的声明 (of ):

let lexbuf = ... in
let wordlist = ...

在模块外层以外的所有地方,let必须跟在in. 这是声明局部变量(在任何表达式中)的方式。

let v = expr1 in expr2

我不清楚你想成为全球性的名字。但解决问题的一种方法是删除第一个in. 然后您将拥有三个全局名称lexbufwordlistwordMap

另一种方法是in在定义之后添加wordlist. 那么你将没有全局名称。

于 2015-10-07T07:26:31.340 回答
0

你的let-bindings. 如果我将您的重写如下:

    let main () =
      let lexbuf = Lexing.from_channel stdin in
      let wordlist =
         let rec next l = match token lexbuf with
            EOF -> l
          | Word s -> next (s :: l) in
         next [] 
      in
     wordlist

   let wordMap = StringMap.empty

函数作为结果main返回wordList

于 2015-10-07T07:27:22.327 回答
0

解决此类问题的黄金法则:使用适当的缩进工具、caml-mode、tuareg-mode 或 ocp-indent。如果这些工具显示的缩进与您的意图不同,则通常是您犯了语法错误。

于 2015-10-07T08:07:18.460 回答