我正在尝试从sml中的char列表中删除空条目。
这是我的功能,但是当我尝试调用它时,它不起作用并带来致命错误。
fun no_spaces([]) = raise Empty
| no_spaces(e::f) = if(e = #" ") then no_spaces(f) else e::no_spaces(f);
no_spaces [#"a",#"a",#" ",#"d",#" "];
我做错了什么?
谢谢
P.S或者如果这不可能,那么如何从字符串中删除空格?
答案 0 :(得分:1)
我怀疑raise Empty
你意味着返回空列表而不是触发运行时错误。你已经在评论中指出你已经修复了那个特定的bug,但是当你应该返回nil以及什么时候应该提高空的时候再多说一点也不会有什么坏处。
作为一般经验法则,如果要定义一个向列表发送列表的函数,并且通过逐个处理输入列表的元素来构造输出列表(例如,返回int列表中的偶数元素列表,其中涉及依次检查每个元素的奇偶校验)然后你的基础情况应该是类似fun f [] = []
的东西,因为空输入对应于什么都没有留下来处理,如果没有什么可以处理,那么没有什么可留给返回。
但是 - 如果列表上的函数的目标是返回列表的元素(例如第一个偶数条目),那么raise Empty
很自然:
fun firstEven [] = raise Empty
| firstEven (x::xs) = if x mod 2 = 0 then x else firstEven xs;
此处raise Empty
非常完美:由于[]
不包含任何整数,因此它不包含第一个甚至返回的整数。因此,这是一个错误情况,(理想情况下)应该在调用函数的某处用handle
来解决。
可以断言raise Empty
永远不应该使用,因为SML提供了一种使用option
类型构造函数的替代错误处理方法。函数firstEven
可以重写
fun firstEven [] = NONE
| firstEven (x::xs) = if x mod 2 = 0 then SOME x else firstEven xs;
在这种情况下,调用函数将对返回的值进行模式匹配(使用两个模式NONE
和SOME x
),而不是提供异常处理程序。从概念上讲,第二种方法更清晰,可能更有效(似乎在F#中,见this,我不确定SML)。
有关SML中两种错误处理方法的讨论,请参阅this。