【问题标题】:Non exhaustive search error in SML n-ary treeSML n-ary 树中的非穷举搜索错误
【发布时间】:2015-11-02 10:42:17
【问题描述】:

我正在尝试使用 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 叉树数据结构

datatype 'a ntree = leaf of 'a | node of 'a ntree list;

错误是get如下

 `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`
  `

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

【问题讨论】:

    标签: sml smlnj


    【解决方案1】:

    您缺少cat (node xs) 的定义,其中xs 的元素少于2 个。

    node 模式只是底层的列表——因此您应该遵循基本的 SML 模式,即在列表上定义一个函数,为空列表提供定义,然后为看起来像 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 构造函数中,然后再馈送到cat

    SML 不完全包括电池 - 但Standard ML Basis Library 有一些好东西。有一个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
    

    第一种方法可以被认为是定义类似concatWith 的东西,带有硬连线分隔符(“”),并且在树数据类型中的节点列表的特殊情况下。

    【讨论】:

    • 你能在这里发布完整的代码吗?我无法在这里得到第一个定义要写的内容。
    • @CyprUS 我认为这可能是家庭作业,所以我没有给出完整的代码。我对其进行了编辑以填写详细信息。
    • @CyprUS 好奇心很好 :) 你的代表太高了,你不能成为那种要求别人为他们做作业的人,但你结束问题的方式向我暗示也许您是在要求家庭作业提示。当您询问 cmets 中的详细信息时,我非常确信这不是家庭作业。
    • 我只是希望我自己想通了。没有多少文献可以正确地指导人们解决这些棘手的问题,因此我依赖于 SO。此外,没有针对 SML 的调试器,这在涉及复杂数据结构时会变得更加困难
    • ML 中的非学术工作可能应该在方言 Ocaml 或 F# 中完成,因为它们有更多工具和更多最新书籍。在 SML 中,我对调试器的需求与在其他语言中的需求不同,但毫无疑问它会派上用场。我还没有使用它,但是 PolyML(它是 SML + 一些扩展的完整实现)拥有一个调试器。见polyml.org
    猜你喜欢
    • 2012-07-01
    • 2014-06-02
    • 2015-04-07
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 2014-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多