trying to take a string and make all the characters capitalized
To convert a string to uppercase,
- val allCaps = String.map Char.toUpper;
- allCaps "Hello World!";
> val it = "HELLO WORLD!" : string
For some general feedback on your code,
(Logical error) toCaps
takes two arguments, (1) the exploded string, and (2) an empty list. But you call the exploded string acc
and pattern match against nil
/h::t
on the empty list; you probably want it the other way around.
(Type error) You write toCaps ((acc::t), ...)
, which means putting acc
, a list, in front of t
, another list. But acc
is itself a list of the same kind as t
; lists can only contain elements of the same kind, so they can't contain elements of their own type.
You don't need to nest let-expressions; one let-expression can have multiple declarations:
fun allCaps s =
let val L = explode s
fun toCaps ...
in ... end
You don't need type annotations unless it improves clarity; the compiler will infer the type.
Converting a string to a list of chars, recursing over that list, and converting the list back to a string, is inefficient but a good learning exercise in list recursion. Here's a revised version of your code:
fun allCaps s =
let fun upper (c::cs) = Char.toUpper c :: upper cs
| upper [] = []
in implode (upper (explode s)) end
This function isn't tail-recursive; for very long strings, upper
's calls to itself might eventually exhaust stack memory. You can avoid this by only making tail-calls and by keeping the accumulated result in heap memory by using a function argument as temporary storage:
fun allCaps s =
let fun upper (c::cs, acc) = upper (cs, Char.toUpper c :: acc)
| upper ([], acc) = rev acc
in implode (upper (explode s, [])) end
The drawback is that when you push the first character from c::cs
into the front of acc
, they end up in reverse order and you need to reverse the result again before imploding it.
Either way, the string-only solution presented at the top uses less memory because it only needs to create a single string the same size as the input and loop over the indices of the input string.