stringlistrecursionsml

SML list option recusion; how to use recursion to output a SOME list


Currently, my code takes in a string s and a string list sl and returns a string list where s was removed (once)

fun all_except_option (s, sl) =
    case sl of
    [] => []
      | hd::tl = if same_string(s, hd)
          then tl
          else hd::all_except_option(s, tl) 

However, what I want is to return NONE if the string s is not in the list and if it is, return SOME (output of the current function). However, I can't simply add SOME( before hd::all_except_option(s, tl) since hd will be appended to something that outputs an option and I can't figure how to do it.

Edit: thanks everyone!


Solution

  • fun all_except_option (s, ss) =
        case ss of
          [] => NONE
        | s'::ss' =>
            if s = s' then SOME ss' else
            case all_except_option (s, ss') of
              NONE => NONE
            | SOME ss'' => SOME (s'::ss')
    

    Note that this only removes the first occurrence of s, which mirrors your version.

    You can also use Option.map to avoid the nested case:

    fun all_except_option (s, ss) =
        case ss of
          [] => NONE
        | s'::ss' =>
            if s = s' then SOME ss'
            else Option.map (fn ss' => s'::ss') (all_except_option (s, ss'))