I know ML has a bunch of string methods (substring, etc) that would make this easier but I want to get more comfortable with the language, so I'm implementing some myself.
I'm trying to truncate a string, i.e. cut off the string after a certain number of characters. I think I'm very close but am getting a syntax error when I do
val x::xs = explode(myString);
Here's the full code:
fun getAllButLast([x]) = nil
| getAllButLast(x::xs) = x::getAllButLast(xs);
fun truncate(myString, 0) = ""
| truncate(myString, limit:int) =
let
val x::xs = explode(myString);
in
x::truncate(implode(getAllButLast(xs)), limit - 1)
end;
Thoughts on why the compiler doesn't like this?
val x::xs = explode(myString);
Thanks for the help, bclayman
Edit to include error:
Ullman.sml:82.5-82.55 Error: operator and operand don't agree [tycon mismatch]
operator domain: char * char list
operand: char * string
in expression:
x :: truncate (implode (getAllButLast <exp>),limit - 1)
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
As the error message shows, it is complaining about a different line. And it is complaining because the right operand of the ::
operator in that line (the result of the recursive call to truncate
) is a string, not a list. You probably want to use ^
instead, which denotes string concatenation.
Hint: There are other issues with your code. At least it is extremely inefficient. You should generally avoid implode/explode, but if you must use them, you should at least only call each of them once for the whole string, and not once for every character in the recursion.