有人可以帮我解释为什么我在这一行有语法错误: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;;
我知道它什么都不打印,这只是为了测试。
答案 0 :(得分:2)
声明如下:
let v = expr
只能出现在模块的最外层。这是声明模块全局名称的方法。
但是你在表达式中有这样的声明(wordlist
):
let lexbuf = ... in
let wordlist = ...
在模块外层以外的所有位置,let
必须后跟in
。这是声明局部变量(在任何表达式中)的方法。
let v = expr1 in expr2
我不清楚你想要哪些名字是全球性的。但解决问题的一种方法是删除第一个in
。然后,您将拥有三个全局名称lexbuf
,wordlist
和wordMap
。
另一种方法是在in
的定义之后添加wordlist
。那你就没有全球名字了。
答案 1 :(得分: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
作为结果。
答案 2 :(得分:0)
这种麻烦的黄金法则:使用适当的缩进工具,caml-mode,tuareg-mode或ocp-indent。如果这些工具显示的缩进与您的意图不同,通常会出现语法错误。