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

Thu*_*ing 2 functional-programming ml sml smlnj

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

  • 字符串列表 L
  • 字符串
  • 整数计数器

该函数应返回strin的出现次数L

这是我的代码:

(* 
 * 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
Run Code Online (Sandbox Code Playgroud)

这些是我得到的错误:

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
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 语法有什么问题?
  2. 我不清楚错误消息说的是什么:在这种情况下,a rule和 anobject是什么?
  3. 如何int通过递归调用函数返回 a ?是通过将 acounter作为参数传递给它吗?

Ant*_*nov 5

这是一个经典的错误:tl(L)而且tl L是同一件事——在类似 ML 的语言中,函数应用程序不需要括号,只需将函数和参数并置即可。

所以aux_num_of_occur tl(L) ...是同样的事情aux_num_of_occur tl L ...,即你正在尝试应用aux_num_of_occurtl功能,而不是字符串列表。现在,该tl函数具有类型'a list -> 'a list,这就是您在错误消息中看到的内容('a'Z那里)。

我应该说,这种风格与那些nullhdtl功能还不是很习惯在SML -你可以使用模式mathing代替。也可以更方便地使aux_num_of_occurlocal 防止命名空间污染,防止错误使用(您控制 的初始值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
Run Code Online (Sandbox Code Playgroud)

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

警告:调用 polyEqual

您可以忽略或添加一些类型注释到num_of_occur. 有关更多详细信息,请参见此处

  • @SimonShine 或者,如果我想(并说明 `if` 是一个表达式):`fun num_of_occur ss str = foldl (fn (s, count) =&gt; count + (if s = str then 1 else 0 )) 0 秒` (3认同)
  • 此外,这是折叠的样子:`fun num_of_occur ss str = foldl (fn (s, count) =&gt; if s = str then count + 1 else count) 0 ss` (2认同)
  • @SimonShine 我认为这属于它自己的答案!查找这个问题的人应该能够看到简洁、惯用的高阶解决方案以及显式递归解决方案(但是,为了清楚起见,请命名您的辅助函数!):)。 (2认同)