SML n-ary树中的非穷举搜索错误

时间:2015-11-01 23:24:29

标签: sml smlnj

我正在尝试使用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`
  `

我该如何解决这个问题?相反,请指出如何继续调试的方向。

1 个答案:

答案 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 的内容,以及树数据类型中节点列表的特殊情况。