从char列表中删除空格 - sml

时间:2015-11-05 02:20:17

标签: sml smlnj

我正在尝试从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或者如果这不可能,那么如何从字符串中删除空格?

1 个答案:

答案 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;

在这种情况下,调用函数将对返回的值进行模式匹配(使用两个模式NONESOME x),而不是提供异常处理程序。从概念上讲,第二种方法更清晰,可能更有效(似乎在F#中,见this,我不确定SML)。

有关SML中两种错误处理方法的讨论,请参阅this