Thu*_*ing 2 functional-programming ml sml smlnj
我是 ML 的新手,这是我尝试编写一个接收的函数:
该函数应返回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)
我的问题:
rule和 anobject是什么?int通过递归调用函数返回 a ?是通过将 acounter作为参数传递给它吗?这是一个经典的错误: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 -你可以使用模式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. 有关更多详细信息,请参见此处。