SML 列表选项回避;如何使用递归输出 SOME 列表
SML list option recusion; how to use recursion to output a SOME list
目前,我的代码接受一个字符串 s
和一个字符串列表 sl
和 returns 一个字符串列表,其中 s
被删除(一次)
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)
但是,我想要的是 return NONE
如果字符串 s
不在列表中,如果在列表中,则 return SOME (
当前函数的输出)
。但是,我不能简单地在 hd::all_except_option(s, tl)
之前添加 SOME(
,因为 hd
将附加到输出选项的内容,我不知道该怎么做。
编辑:谢谢大家!
听起来你需要一个新功能:
fun some_option(s,sl) = SOME( all_except_option(s, sl) )
嗯,不完全是这样,因为它不处理 all_except_option
returns []
的情况,但我会把它留作练习。
您可以使用
case all_except_option(s, tl) of ...
匹配两种不同的情况并以适当的方式处理每一种情况。
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')
请注意,这只会删除第一次出现的 s
,它反映了您的版本。
您也可以使用 Option.map
来避免嵌套:
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'))
Andreas Rossberg 提供了两个完整的示例。
这里是模式匹配在函数参数中的变体:
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))
其中 curry op:: t
是接受列表并将 t
放在它前面的函数:
- curry op:: "x" ["y", "z"];
> val it = ["x", "y", "z"] : string list
等价于 fn ss' => t::ss'
.
如果你像我一样苦苦挣扎,花了太多时间来解决课程中的那个问题,这里有一个你可以简单理解的解决方案:
(* 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
目前,我的代码接受一个字符串 s
和一个字符串列表 sl
和 returns 一个字符串列表,其中 s
被删除(一次)
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)
但是,我想要的是 return NONE
如果字符串 s
不在列表中,如果在列表中,则 return SOME (
当前函数的输出)
。但是,我不能简单地在 hd::all_except_option(s, tl)
之前添加 SOME(
,因为 hd
将附加到输出选项的内容,我不知道该怎么做。
编辑:谢谢大家!
听起来你需要一个新功能:
fun some_option(s,sl) = SOME( all_except_option(s, sl) )
嗯,不完全是这样,因为它不处理 all_except_option
returns []
的情况,但我会把它留作练习。
您可以使用
case all_except_option(s, tl) of ...
匹配两种不同的情况并以适当的方式处理每一种情况。
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')
请注意,这只会删除第一次出现的 s
,它反映了您的版本。
您也可以使用 Option.map
来避免嵌套:
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'))
Andreas Rossberg 提供了两个完整的示例。
这里是模式匹配在函数参数中的变体:
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))
其中 curry op:: t
是接受列表并将 t
放在它前面的函数:
- curry op:: "x" ["y", "z"];
> val it = ["x", "y", "z"] : string list
等价于 fn ss' => t::ss'
.
如果你像我一样苦苦挣扎,花了太多时间来解决课程中的那个问题,这里有一个你可以简单理解的解决方案:
(* 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