问题描述
我有一个方法可以返回列表(特别是char值列表)中最常见元素的计数
这是我的代码:
let getMostFrequentCharCount li =
let hashTable = Hashtbl.create (List.length li)
in
let rec getMostFrequentCharCount li acc =
match li with
[] -> acc
| head::tail ->
(match (Hashtbl.find hashTable head) with
exception Not_found -> Hashtbl.add hashTable head 1
| _ -> let currentFreq = Hashtbl.find hashTable head
in
Hashtbl.replace hashTable head (currentFreq+1));
let currentFreq = Hashtbl.find hashTable head
in
if currentFreq > acc
then
getMostFrequentCharCount tail currentFreq
else
getMostFrequentCharCount tail acc
in
getMostFrequentCharCount li 0;;
由于某种原因,当我删除第二个模式匹配块(以match (Hashtbl.find hashTable head) with
开头)的括号时,编译器抱怨我的累加器acc
在下一个if语句{{ 1}},而if currentFreq > acc
的类型应为acc
。
解决方法
在OCaml语法中,match
分支(在->
之后)包含由;
分隔的表达式的序列。因此,如果没有括号,则会将以下行作为match
的{{1}}分支的一部分进行解析。
由于_
返回unit,因此该匹配的第一个分支的类型为unit。这意味着Hashtbl.add
分支也必须是unit类型。如果没有括号,则以下行会导致类型错误,因为它们不是unit类型。
我使用ocamlformat格式化带括号和不带括号的外部_
。
这是带括号的格式化代码:
match
以下是带括号的格式化代码:
match li with
| [] -> acc
| head :: tail ->
( match Hashtbl.find hashTable head with
| exception Not_found -> Hashtbl.add hashTable head 1
| _ ->
let currentFreq = Hashtbl.find hashTable head in
Hashtbl.replace hashTable head (currentFreq + 1) );
let currentFreq = Hashtbl.find hashTable head in
if currentFreq > acc then getMostFrequentCharCount tail currentFreq
else getMostFrequentCharCount tail acc
我认为这很好地说明了问题。