子句的右侧与函数结果类型不一致
right-hand-side of clause doesn't agree with function result type
写一个函数remove_option,接受一个字符串和一个字符串列表。 Return NONE 如果字符串不在列表中,否则 return SOME xs 其中 xs 与参数列表相同,只是字符串不在其中。您可以假设该字符串最多出现在列表中一次。使用提供给您的 same_string 来比较字符串。示例解决方案大约有 8 行。
函数类型应该是 fn : string * string list -> string list option.Here 是我的代码
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
那么错误在哪里?
问题是你想 return 一个 string list option
但行
else x :: remove_option( str,xs)
看起来你想要return一个string list
你需要用remove_option( str,xs)
的return值做的是
1) 如果是NONE
,决定怎么办
2) 提取字符串列表 strings
(或任何你想称呼它的东西)如果它的形式是 SOME strings
,将 x
添加到列表的前面,并在 return 之前用 SOME
重新打包它。
您似乎对 case
的使用感到满意,因此您可以在此处使用它。
由于 John 指出了漏洞所在,这里有一些额外的评论:
- 由于函数
same_string
没有被注入,所以是多余的。您不妨使用 =
.
return'一个选项的递归函数有点棘手,因为您需要解压结果:
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
放在列表前面的函数。
写一个函数remove_option,接受一个字符串和一个字符串列表。 Return NONE 如果字符串不在列表中,否则 return SOME xs 其中 xs 与参数列表相同,只是字符串不在其中。您可以假设该字符串最多出现在列表中一次。使用提供给您的 same_string 来比较字符串。示例解决方案大约有 8 行。
函数类型应该是 fn : string * string list -> string list option.Here 是我的代码
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
那么错误在哪里?
问题是你想 return 一个 string list option
但行
else x :: remove_option( str,xs)
看起来你想要return一个string list
你需要用remove_option( str,xs)
的return值做的是
1) 如果是NONE
2) 提取字符串列表 strings
(或任何你想称呼它的东西)如果它的形式是 SOME strings
,将 x
添加到列表的前面,并在 return 之前用 SOME
重新打包它。
您似乎对 case
的使用感到满意,因此您可以在此处使用它。
由于 John 指出了漏洞所在,这里有一些额外的评论:
- 由于函数
same_string
没有被注入,所以是多余的。您不妨使用=
. return'一个选项的递归函数有点棘手,因为您需要解压结果:
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
放在列表前面的函数。