编写一个函数remove_option,它接受一个字符串和一个字符串列表。如果字符串不在列表中,则返回NONE,否则返回SOME xs,其中xs与参数列表相同,但字符串不在其中。您可以假设字符串最多只在列表中一次。使用提供给您的same_string来比较字符串。样品溶液约为8行。
函数类型应为fn:string * string list - >字符串列表选项。这是我的代码
fun same_string(s1 : string, s2 : string) =
s1 = s2
fun remove_option (str: string ,str_list : string list) =
case str_list of
[] => NONE
| x::xs => if same_string(x,str)
then SOME xs
else x :: remove_option( str,xs)
和错误报告
hw2provided.sml:10.5-15.37 Error: right-hand-side of clause doesn't agree with f
unction result type [tycon mismatch]
expression: _ option
result type: string list
in declaration:
remove_option =
(fn (<pat> : string,<pat> : string list) =>
(case str_list
of <pat> => <exp>
| <pat> => <exp>))
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:292.17-292.20
那么bug在哪里?
答案 0 :(得分:5)
问题是您要返回string list option
但行
else x :: remove_option( str,xs)
似乎要返回string list
您需要对remove_option( str,xs)
的返回值执行
1)决定如果是NONE
2)提取字符串列表strings
(或任何你想要称之为的内容),如果它的格式为SOME strings
,将x
添加到列表的前面,并重新打包在返回之前使用SOME
。
您对case
的使用感到满意,因此您可以在此处使用它。
答案 1 :(得分:3)
由于约翰显示了错误的位置,这里有一些额外的评论:
same_string
,因此它是多余的。您也可以使用=
。返回'一个选项的递归函数有点棘手,因为你需要解压缩结果:
fun remove_option (s1, []) = NONE
| remove_option (s1, s2::ss) =
if s1 = s2
then SOME ss
else case remove_option (s1, ss) of
NONE => NONE
| SOME ss' => SOME (s2::ss')
通常,当您看到模式
时case x_opt of
NONE => NONE
| SOME x => SOME (f x))
这可以重构为使用例如Option.map : ('a -> 'b) -> 'a option -> 'b option
:
Option.map f x_opt
在这种情况下,
fun curry f x y = f (x, y)
fun remove_option (s1, []) = NONE
| remove_option (s1, s2::ss) =
if s1 = s2
then SOME ss
else Option.map (curry op:: s2) (remove_option (s1, ss))
其中curry op:: s2
,将s2
放在列表前面的函数。