I'm trying to write a function that converts a lower case character to uppercase (if uppercase, leave unchanged).
Here's what I've written:
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;
I'm getting this compilation error:
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
Am I not allowed to define exceptions within a function as I've done?
Thanks for the help, bclayman
No, you will need to define the exception in a let expression, such as:
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
That said, it is probably better practice to define your exception outside of the let expression, so that it can be caught by the user. For example, if you wanted to do this for a string, one might do:
fun toUppers(str) = String.implode (map toUpper (String.explode str))
There is no way to recover from the invalidCharacter
exception, unless you handle all exceptions (which is generally bad practice):
fun toUppers(str) =
String.implode (map toUpper (String.explode str)) handle e => (*do something*)
Instead we would like:
fun toUppers(str) =
String.implode (map toUpper (String.explode str)) handle invalidCharacter => (*do something*)