Reputation: 89
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!
Upvotes: 1
Views: 518
Reputation: 19
In case you are struggling too much like me and took too much to solve that question from the course, here is a solution for you that you can simply understand:
(* string * string list -> string list option *)
(* Eliminate a specific string from a list of string*)
(* fun all_except_option (s, los) = [] *) (* stub *)
fun all_except_option (exc, los) =
let
fun all_except_option_acc (los, acc, f) =
case los of
[] =>
if f then SOME acc
else NONE
| s::los' =>
if same_string (s, exc) then
all_except_option_acc(los', acc, true)
else
all_except_option_acc(los', s::acc, f)
in
all_except_option_acc(los, [], false)
end
Upvotes: 0
Reputation: 16105
Andreas Rossberg provided two complete examples.
Here is a variation where the pattern matching is in the argument of the function instead:
fun curry f x y = f (x, y)
fun all_except_option (s, []) = NONE
| all_except_option (s, t::ts) =
if s = t
then SOME ts
else Option.map (curry op:: t) (all_except_option (s, ts))
Where curry op:: t
is the function that takes a list and puts t
in front of it:
- curry op:: "x" ["y", "z"];
> val it = ["x", "y", "z"] : string list
and is equivalent to fn ss' => t::ss'
.
Upvotes: 0
Reputation: 36088
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'))
Upvotes: 1
Reputation: 183211
You can use
case all_except_option(s, tl) of ...
to match the two different cases and handle each in the appropriate way.
Upvotes: 0
Reputation: 49803
It sounds like you need a new function:
fun some_option(s,sl) = SOME( all_except_option(s, sl) )
Well, not quite that, as it doesn't handle the case where all_except_option
returns []
, but I'll leave that as an exercise.
Upvotes: 1