Komal Waseem
Komal Waseem

Reputation: 1127

SML: Tail-recursive local helper function

I'm trying to re-write a code using tail recursive local helper function as part of an assignment.

all_except_option is a function that has the return type fn : string * string list -> string list option

fun all_except_option ([], _ ) = NONE
| all_except_option (_, "") = NONE
| all_except_option (str_list, str) =
let
  fun all_except_option' [] = []
    | all_except_option' (x::str_list) =
      if x = str then
        all_except_option' str_list
      else
        x :: all_except_option' str_list
in
  SOME (all_except_option' str_list)
end;

The function below is the one without using tail-recursive local helper function

fun sub1 ([], s) = []
| sub1 (x :: xs, s) =
case all_except_option(x, s) of  NONE => sub1(xs, s) // 
| SOME y => y @ get_substitutions1(xs, s);

This function use tail-recursion however I get an error where I'm calling the helper function recursively. The error is: Error: non-constructor applied to argument in pattern:all_except_option

fun get_substitutions2 (s,str) = 
let fun aux(s,x::xs,acc) =  
    case x of [] => acc
| all_except_option(x, s) => aux(s,xs,xs::acc) 
in 
aux(s,str,[])
end;

Upvotes: 0

Views: 1816

Answers (1)

Diego Sevilla
Diego Sevilla

Reputation: 29021

In both cases you call all_except_option with x (a string) as the first argument, while it is expecting a string list as the first parameter.

Also, the cases of a case cannot be calls to functions but constructors of a type. For example, looking closely at your code:

case x of 
[] => acc
| all_except_option(x, s) => aux(s,xs,xs::acc) 

Note how you're using a function call instead of a type construction of what all_except_option would have returned, and also you're using the construct xs::acc that is not valid in this case, as xs is a list. Finally, x is the head of a list, so it cannot be []. Still not clear to me what that aux function wants to achieve, but these errors are suspicious.

Upvotes: 2

Related Questions