更改为Tail递归SML

时间:2013-10-21 02:35:18

标签: functional-programming sml tail-recursion

好的,所以我正在尝试将此功能更改为Tail Recursive。我有Tail Recursive的定义是使用“Local Helper Function”来累积我的答案并返回它而不用递归调用主函数。

这些功能正常运作。

fun same_string(s1 : string, s2 : string) =
s1 = s2

fun all_except_option (name, []) = NONE
  | all_except_option (name, x::xs)=
case same_string (x , name) of
true  => SOME xs
  | false => case all_except_option(name,xs) of
         NONE   => NONE
           | SOME z => SOME(x::z)

fun get_substitutions1 ([],name2)    = [] (*get_substitutions2 is same but tail recursive *)
  | get_substitutions1 (x::xs,name2) = 
    case all_except_option (name2,x) of
        NONE   => get_substitutions1 (xs,name2)
      | SOME z  => z @ get_substitutions1(xs,name2)

所以这是我在尾部递归时的尝试不起作用,我认为由于缺乏SML经验,我遗漏了一些我忽略的基本内容。

fun get_substitutions2 (lst,name3) = 
let fun aux (xs,acc) =
 case all_except_option(name3,x::xs) of
     NONE   => aux(xs, acc)
   | SOME z => aux(xs, z::acc)
in
aux(lst,[])
end

fun get_substitutions2 (lst,name3) = 
let fun aux (xs,acc) =
 case all_except_option(name3,x::xs) of
     NONE   => aux(xs, acc)
   | SOME z => aux(xs, z@acc)
in
aux(lst,[""])
end

两个“get_substitutions”函数都应该做同样的事情。 将String1与字符串列表列表进行比较,返回由包含String1减去String1的所有列表组成的单个列表。

我尝试使用Tail Recursion导致以下错误。

Error: unbound variable or constructor: x

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-

以下是调用get_substitutions2

的几个示例
get_substitutions2 ([["foo"],["there"]], "foo"); (* = [] *)
get_substitutions2 ([["fred","fredrick","freddie","F","freddy"],["Will","William","Willy","Bill"]],"Bill"); (* = ["Will","William","Willy"] *)
get_substitutions2 ([["a","b"],["a","c"],["x","y"]], "a"); (* = ["c","b"] *) 

1 个答案:

答案 0 :(得分:2)

您需要在get_substitutions1函数定义中使用与aux相同的模式:

fun get_substitutions2 (lst,name3) = 
let fun aux ([],acc) = acc (* BASE CASE *)
      | aux (x::xs,acc) =  (* BINDING x IN PATTERN *)
 case all_except_option(name3,x) of
     NONE   => aux(xs, acc)
   | SOME z => aux(xs, z@acc)
in
aux(lst,[])
end
相关问题