如何查找 ML 字符串列表中的出现次数?

how to find number of occurrences in ML string list?

我是 ML 的新手,这是我尝试编写一个函数来接收:

函数应该returnstrL

中出现的次数

这是我的代码:

(* 
 * return number of occurences of str in L
 * count should be initialized to zero. 
 *)
 fun aux_num_of_occur(L: string list) (str:string) (count:int) =
    if null L then 0
    else if str = hd(L) then
        aux_num_of_occur tl(L) str (count+1)
    else
        aux_num_of_occur tl(L) str count

这些是我得到的错误:

Error: case object and rules don't agree [tycon mismatch]
  rule domain: string list * string * int
  object: ('Z list -> 'Z list) * 'Y * 'X
  in expression:
    (case (arg,arg,arg)
      of (L : string list,str : string,count : int) =>
           if null L
           then 0
           else if <exp> = <exp> then <exp> <exp> else <exp> <exp>)

uncaught exception Error
  raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
             ../compiler/TopLevel/interact/evalloop.sml:44.55
             ../compiler/TopLevel/interact/evalloop.sml:296.17-296.20

我的问题:

  1. 语法有什么问题?
  2. 我不清楚错误消息说的是什么:what is a ruleobject 在这种情况下?
  3. 如何通过递归调用函数来return一个int?是通过将 counter 作为参数传递给它吗?

这是一个典型的错误:tl(L)tl L 是同一件事——在类似 ML 的语言中,函数应用不需要括号,只需将函数和参数。

所以 aux_num_of_occur tl(L) ...aux_num_of_occur tl L ... 是一样的,即您试图将 aux_num_of_occur 应用于 tl 函数,而不是字符串列表。现在,tl 函数的类型为 'a list -> 'a list,这就是您在错误消息中看到的内容(其中 'a'Z)。

我应该说这种带有 nullhdtl 函数的样式在 SML 中不是很惯用——您可以改用模式数学。把aux_num_of_occur设为本地也更方便,防止命名空间污染,防止不正确的使用(你控制count的初始值)。此外,这为您提供了在进一步递归时不会一直传递 str 的优势。

fun num_of_occur ss str =
  let
      fun loop [] count = count
        | loop (s::ss) count =
            if s = str
            then loop ss (count + 1)
            else loop ss count
  in
      loop ss 0
  end

注意 num_of_occur 有一个更通用的类型 ''a list -> ''a -> int,其中 ''a 表示任何具有相等比较的类型。编译器会产生警告

Warning: calling polyEqual

您可以忽略或向 num_of_occur 添加一些类型注释。有关详细信息,请参阅 here