user12513149
user12513149

Reputation:

Standard ML: Using foldr to create a string out of int list

I am Trying to create a function in Standard ML to create a string out of an int list [1,2,3,4] such that it would look like "1, 2, 3, 4".

What I managed to create is a function that would do the job by iterating and converting to string and add ", ". But since i am concating the comma after each iteration, the comma would also end up at the end of the string.

Here is my function:

fun list_string lst =
    (foldr (fn (x, y) => x ^ ", " ^ y ) "" (List.map (fn x => Int.toString(x)) lst));

You can see the problem that once it reaches the end, it will still print the comma. Is there a way i can add a function to the part with foldr so it can check the last element?

Upvotes: 1

Views: 644

Answers (2)

qouify
qouify

Reputation: 3920

You can instead add a comma only if your not on the first item of your list. This can be simply checked by comparing y to the empty string:

fun list_string lst = (List.foldr (fn (x, y) => if y = "" then x else x ^ "," ^ y)
                  "" (List.map (fn x => Int.toString(x)) lst));

print(list_string([1, 2, 3]));

You can also do it with pattern matching and without first mapping your int list into a string list. Hence you traverse your list only once. This is also more readable in my opinion:

fun list_string lst = List.foldr (
      fn (x, "") => (Int.toString x)
      |  (x, y)  => (Int.toString x) ^ "," ^ y) "" lst;
print(list_string([1, 2, 3]));

Upvotes: 1

sshine
sshine

Reputation: 16145

You could do this by folding:

fun commaSep [] = ""
  | commaSep (n0::ns) =
      foldl (fn (n, s) => s ^ ", " ^ Int.toString n) 
            (Int.toString n0)
            ns

Or you could use concat, map and intersperse:

fun intersperse x [] = []
  | intersperse x [y] = [y]
  | intersperse x (y::zs) = y :: x :: intersperse x zs

val commaSep = String.concat
             o intersperse ", "
             o List.map Int.toString

Upvotes: 0

Related Questions