标准 ML:使用 foldr 从 int 列表中创建一个字符串

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

我正在尝试在标准 ML 中创建一个函数,以从 int 列表 [1,2,3,4] 中创建一个字符串,使其看起来像 "1, 2, 3, 4".

我设法创建的是一个函数,它可以通过迭代和转换为字符串并添加“,”来完成这项工作。但是因为我在每次迭代后连接逗号,所以逗号也会在字符串的末尾结束。

这是我的函数:

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

可以看到这个问题,到了最后还是会打印逗号。 有没有一种方法可以使用 foldr 向该部分添加一个功能,以便它可以检查最后一个元素?

只有当您不在列表的第一项时,您才可以添加逗号。这可以通过将 y 与空字符串进行比较来简单地检查:

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]));

您也可以使用模式匹配来完成此操作,而无需先将您的 int 列表映射到字符串列表。因此,您只遍历列表一次。这在我看来也更具可读性:

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

你可以通过折叠来做到这一点:

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

或者您可以使用 concatmapintersperse:

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