I have to write a SML function that returns a sentence consisting of words separated by spaces in the given list. I have to use at least one of foldl/foldr/map functions.
This is what I wrote:
fun add_spaces nil = ""
| add_spaces(x::xs) = foldr (fn (x,xs) => (add_spaces x)^" "^xs) x [xs];
add_spaces(["Testing","function","with","this","sentence"]);
But that function brings a reversed string (sentence this with function Testing). I read in the internet that can be solved by reversing list ([xs] in this case right?) but how can I do that?
Thank you
Your function add_spaces
uses foldr
in a beautifully convoluted but likely misunderstood way.
A regular recursive function, which won't satisfy the criterion of using foldl/foldr/map, is,
fun add_spaces [] = ""
| add_spaces [s] = s
| add_spaces (s::ss) = s ^ " " ^ add_spaces ss
A similar function relying on folding for its recursion would follow a pattern,
fun add_spaces [] = ""
| add_spaces (s1::ss) = fold<l/r> (fn (s,res) => ...) s1 ss
where ...
explicitly does not refer to add_spaces
. Thus, you have at least two instruments to guide the order in which your items arrive. One being the order in which you refer to s
and res
inside the anonymous function in the above template, and the other being your choice of foldl
and foldr
.
Notice also that foldl
and foldr
will traverse the list from different directions; from the left and from the right, respectively. To illustrate the order, try and fold with something that results in side-effects and see which effects arrive first:
- foldl (fn (s, _) => print (s^"\n")) () ["Hello", "World!"];
Hello
World!
> val it = () : unit
- foldr (fn (s, _) => print (s^"\n")) () ["Hello", "World!"];
World!
Hello