문제

Ok, so I'm trying to change this function into Tail Recursive. The Definition I have of Tail Recursive is to use a "Local Helper Function" to accumulate my answer and return it without calling the primary function recursively.

these functions work properly.

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)

So here are my attempts at tail recursion which do not work and I think I am missing something fairly basic that I am overlooking due to my lack of experience in 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

and

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

Both "get_substitutions" functions are supposed to do the same thing. compare String1 to string list list, return single list made up of all lists containing String1 minus String1.

My attempts at using Tail Recursion have resulted in the following error.

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-

Here are a few examples of calling 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"] *) 
도움이 되었습니까?

해결책

You need to use the same patterns you had for get_substitutions1 in your aux function definition:

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top