泰康不匹配的问题

时间:2018-09-20 23:18:45

标签: sml smlnj

从事一项基本上需要一棵树的作业,该树的声明是:

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}

虽然我确实知道它是类型冲突,但是我找不到冲突,也找不到解决方法。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

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)

答案 1 :(得分:0)

尽管我也更喜欢像molbdnilo这样的 case-of 来编写此功能,但这里有一个使用 let-in-end 演示它们都可以使用的示例当结果是乘积(元组)时。由于if-then-else中的三种情况具有三个不同的结果(dl > drdr > 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