【问题标题】:Issue with a tycon mismatchtycon 不匹配的问题
【发布时间】:2019-02-25 07:44:34
【问题描述】:

做一个基本上需要一棵树的家庭作业,它的声明是:

datatype a BinTree = 
Leaf of a
| Node of a BinTree * a BinTree;

并返回树的 int 高度的元组和存储在树最深部分的值列表。

fun deepest tree = 
case tree of 
Leaf(n) => [n]
| Node(l, r) => if #1(deepest l) > #1(deepest r) then ((#1(deepest l) + 1), #2(deepest l)) else
                if #1(deepest l) < #1(deepest r) then ((#1(deepest r) + 1), #2(deepest r)) else
                (1, #2(deepest l) @ #2(deepest r)); 

试图测试这段代码,我想出了以下错误消息:

stdIn:43.1-47.35 Error: types of rules don't agree [tycon mismatch]
earlier rule(s): 'Z BinTree -> 'Z list
this rule: 'Z BinTree -> [+ ty] * 'Y list
in rule:
Node (l,r) =>
  if (fn <rule>) (deepest <exp>) > (fn <rule>) (deepest <exp>)
  then (<exp> <exp> + 1,(fn <rule>) (deepest <exp>))
  else if <exp> <exp> < <exp> <exp>
       then (<exp> + <exp>,<exp> <exp>)
       else (1,<exp> @ <exp>)
stdIn:21.2-47.35 Error: right-hand-side of clause doesn't agree with 
function result type [type mismatch]
expression:  'Z list
result type:  {1:[+ ty], 2:'X list; 'Y}
in declaration:
deepest =
  (fn tree =>
        (case tree
          of <pat> => <exp>
           | <pat> => <exp>))
stdIn:1.2-47.35 Error: unresolved flex record (need to know the names of ALL 
the fields
in this context)
type: {1:[+ ty], 2:'Y list; 'Z}

虽然我知道这是一种类型冲突,但我找不到冲突是什么,也找不到解决方法。任何帮助将不胜感激。

【问题讨论】:

    标签: sml smlnj


    【解决方案1】:

    虽然我也更喜欢像 molbdnilo 这样的 case-of 来编写这个函数,但这里有一个使用 let-in-end 的例子来证明它们都可以使用当结果是一个产品(元组)。由于 if-then-else 中的三种情况具有三种不同的结果(dl &gt; drdr &gt; dldl = dr),因此使用 Int-compare 可能更可取:

    fun deepest (Leaf n) = (1, [n])
      | deepest (Node (l, r)) =
        let val (lcount, ls) = deepest l
            val (rcount, rs) = deepest r
        in case Int.compare (lcount, rcount) of
                GT => (lcount + 1, ls)
              | LT => (rcount + 1, rs)
              | EQ => (lcount + 1, ls @ rs)
        end
    

    【讨论】:

      【解决方案2】:

      这个

      earlier rule(s): 'Z BinTree -> 'Z list
      

      来自叶子案例 ([n]),使其成为从树到列表的函数。

      还有这个:

      this rule: 'Z BinTree -> [+ ty] * 'Y list
      

      来自节点案例,使其成为从树到“支持加法的类型”和列表对的函数。

      剩余的错误是由于 SML 无法在存在冲突的情况下推断出 #1#2 的含义。

      您的基本情况是错误的——它应该是一对,而不是一个列表。
      该对中的深度应为 1,在两个子树的深度相同的情况下,深度不应为 1。

      在最坏的情况下,您还要为每个子树计算三次最深值,在最好的情况下计算两次。
      每个子树最好只递归一次。

      类似这样的:

      fun deepest (Leaf n) = (1, [n])
        | deepest (Node (l, r)) =
              case deepest l of (dl, ll) =>
              case deepest r of (dr, lr) =>
                            if dl > dr then (dl + 1, ll)
                            else if dr > dl then (dr + 1, lr)
                            else (dl + 1, ll @ lr)
      

      【讨论】:

        猜你喜欢
        • 2013-10-21
        • 2015-01-24
        • 1970-01-01
        • 2023-04-10
        • 2014-12-30
        • 1970-01-01
        • 1970-01-01
        • 2017-02-07
        • 2021-08-26
        相关资源
        最近更新 更多