标准 ML:大写字符的基本转换

Standard ML: Basic Conversion to Uppercase Character

我正在尝试编写一个将小写字符转换为大写字符的函数(如果是大写,则保持不变)。

这是我写的:

fun toUpper(myChar) =
    exception invalidCharacter;
    if ord(myChar) >= ord(#"A") andalso ord(myChar) <= ord(#"Z") then myChar
    else
        if ord(myChar) >= ord(#"a") andalso ord(myChar) <= ord("z") then
            chr(ord(myChar) - (ord(#"a") - ord(#"A")));
        else raise invalidCharacter;

我遇到这个编译错误:

Ullman.sml:66.12 Error: syntax error: inserting  EQUALOP

uncaught exception Compile [Compile: "syntax error"]
  raised at: ../compiler/Parse/main/smlfile.sml:15.24-15.46
             ../compiler/TopLevel/interact/evalloop.sml:44.55
             ../compiler/TopLevel/interact/evalloop.sml:292.17-292.20

是否不允许像我这样在函数内定义异常?

感谢您的帮助, 克莱曼

不行,你需要在let表达式中定义异常,比如:

fun toUpper(myChar) =
  let exception invalidCharacter;
  in if ord(myChar) >= ord(#"A") andalso ord(myChar) <= ord(#"Z") then myChar
     else
      if ord(myChar) >= ord(#"a") andalso ord(myChar) <= ord(#"z") then
          chr(ord(myChar) - (ord(#"a") - ord(#"A")))
      else raise invalidCharacter
  end

也就是说,在 let 表达式之外定义异常可能是更好的做法,这样它就可以被用户捕获。例如,如果您想对字符串执行此操作,可以这样做:

fun toUppers(str) = String.implode (map toUpper (String.explode str)) 

无法从 invalidCharacter 异常中恢复,除非您处理所有异常(这通常是不好的做法):

fun toUppers(str) =  
  String.implode (map toUpper (String.explode str)) handle e => (*do something*)

相反,我们希望:

fun toUppers(str) =  
  String.implode (map toUpper (String.explode str)) handle invalidCharacter => (*do something*)