我是ML的新手,这是我尝试写一个接收的函数:
该函数应返回str
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
这些是我得到的错误:
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
我的问题:
rule
和object
?int
?是通过传递counter
作为参数吗? 答案 0 :(得分:4)
这是一个经典的错误: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
)。
我应该说,这些null
,hd
和tl
函数的样式在SML中并不是非常惯用 - 你可以使用pattern-mathing代替。使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
表示具有相等性比较的任何类型。编译器将生成警告
警告:调用polyEqual
您可以忽略或向num_of_occur
添加一些类型注释。有关详细信息,请参阅here。