SML / ML Int到String转换

我有这个代码:
datatype 'a Tree = Empty | LEAF of 'a | NODE of ('a Tree) list;
val iL1a = LEAF 1;
val iL1b = LEAF 2;
val iL1c = LEAF 3;
val iL2a = NODE [iL1a, iL1b, iL1c];
val iL2b = NODE [iL1b, iL1c, iL1a];
val iL3 = NODE [iL2a, iL2b, iL1a, iL1b];
val iL4 = NODE [iL1c, iL1b, iL3];
val iL5 = NODE [iL4];

fun treeToString f Node = let
    fun treeFun (Empty) = ["(:"]
    | treeFun (NODE([])) = [")"]
    | treeFun (LEAF(v)) = [f v]
    | treeFun (NODE(h::t)) = [""] @ ( treeFun (h)) @ ( treeFun (NODE(t)) )
    in
    String.concat(treeFun Node)
end;

treeToString Int.toString iL5;
当我运行我的功能时,我得到输出:“32123)231)12)))”。 答案应该是“((32((123)(231)12)))”。 我已经尝试修改我的功能添加(在每个地方我都能想到,但我无法弄清楚我应该在哪里添加“(”。我搞砸了哪里? 编辑:我相信我需要在某处使用map或List.filter,但我不知道在哪里。     
已邀请:
看起来你的列表节点尾部的递归方法就是问题所在。而不是
treeFun h
附加到
treefun (NODE(t))
,尝试将此用于NODE案例:
 treeFun (NODE(items)) = ["("] @ List.concat (map treeFun items) @ [")"]
也就是说,将
treeFun
映射到节点的整个内容上,并用
"("
")"
包围结果。这个定义可能有点太简洁了,你无法理解发生了什么,所以这里有一个更详细的形式,你可能会发现更清楚:
| treeFun (NODE(items)) =
  let val subtree_strings : string list list = map treeFun items
      val concatenated_subtrees : string list = List.concat subtree_strings
      in ["("] @ concatenated_subtrees @ [")"]
      end
subtree_strings
是获取给定节点中所有子树的结果,并通过在每个子树上递归调用
treeFun
将它们中的每一个转换为字符串列表。由于
treeFun
每次调用时都会返回一个字符串列表,并且我们在整个子树列表中调用它,结果是相应的子树列表列表。所以,例如,如果我们打电话给
map treeFun [LEAF 1, LEAF 2, LEAF 3]
,我们就会回来
[["1"], ["2"], ["3"]]
。 这不是我们想要的答案,因为它是字符串列表而不是普通字符串列表的列表。我们可以使用
List.concat
来修复它,它会获取列表列表,并形成所有基础项的单个列表。所以例如
List.concat [["1"], ["2"], ["3"]]
返回
["1", "2", "3"]
。现在我们所要做的就是将括号括在结果周围,我们就完成了。 请注意,此策略对于完全空的节点也适用于具有一个或多个子树的节点,因此无需在原始定义中使用第二种情况
treeFun
。通常,在ML中,如果一个参数的函数对于参数类型的每个构造函数没有一个唯一的情况,那么它就是代码气味。     

要回复问题请先登录注册