我正在尝试使用SML进行编码并面对下面列出的问题 我创建了一个N-Ary树,变量tr存储了树的值。
val tr =node([leaf "x", node([leaf "y", leaf "x" , leaf "z"])]);
函数cat是我希望打印所有叶节点的值。 但是我得到了一个非详尽的搜索警告,但它不起作用。
fun cat (node ( [node t1 , node t2])) = cat(node t1) ^" "^cat(node t2)
| cat ( node ([leaf x, node t1])) = x ^" "^cat(node t1)
| cat( leaf x) = x
这是我的n-ary树的数据结构
datatype
'a ntree = leaf of 'a | node of 'a ntree list;
错误是获得如下
`val tr = node [leaf "x",node [leaf "y",leaf "x",leaf "z"]] : string ntree
.\printValues.sml:14.5-16.20 Warning: match nonexhaustive
node (node t1 :: node t2 :: nil) => ...
node (leaf x :: node t1 :: nil) => ...
leaf x => ...
val cat = fn : string ntree -> string
- cat(tr);
uncaught exception Match [nonexhaustive match failure]
raised at: .\printValues.sml:16.20`
`
我该如何解决这个问题?相反,请指出如何继续调试的方向。
答案 0 :(得分:1)
您缺少cat (node xs)
xs
少于2个元素的定义。
node
模式只是一个列表 - 所以你应该遵循在列表上定义函数的基本SML模式,为空列表提供一个定义,然后为{{{ 1}}。在您的情况下,您可能希望分别处理看起来像x::xs
的模式,以便最后不会有任何杂散空间。以下作品:
node [x]
我将fun cat (leaf x) = x
| cat (node []) = ""
| cat (node [x]) = cat x
| cat (node (x::xs)) = cat x ^ " " ^ cat (node xs);
模式向上移动 - 因为对我来说这是一个基础案例,按照惯例,首先列出案例。树定义的一个特性是它允许非分支父节点。例如,
leaf x
完全有效。案例node[node[leaf "x"]]
旨在剥离那些有点无意义的中间节点。最后一个子句中的一个巧妙之处是,如果cat (node [x]) = cat x
是一个树列表,那么它本身就不是一棵树,所以它必须在被送到xs
之前包装在node
构造函数中。
SML并不完全包含电池 - 但Standard ML Basis Library有一些好处。 cat
是一个String.concatWith
函数。如果你可以使用它,那么有一种灵活的方式来写你想要的东西:
join
使用样本的输出:
fun cat (leaf x) = x
| cat (node branches) = String.concatWith " " (map cat branches);
可以将第一种方法视为使用硬连线分隔符(“”)定义类似cat tr;
val it = "x y x z" : string
的内容,以及树数据类型中节点列表的特殊情况。