以毫升为单位的圆圈误差

时间:2013-04-16 06:30:17

标签: ml

我正在尝试运行一个函数subst(tr,v1,v2),它返回一个新的ntree,其中v1的所有值都被输出树中的v2替换。

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

fun map(f, []) = [] | map(f,x::t)=f(x) :: map(f,t);

fun subst(leaf(d), v1, v2) = if d=v1 then v2 else d
  | subst(node(q), v1, v2) = let fun w(k) =
  if k=v1 then subst(v2, v1, v2) else subst(k, v1, v2)
  in map(w, q)
  end;

但是我得到了循环错误b / c我的rhs of clause与函数结果类型不一致。我的表达式是''Z列表,我的结果类型是''Z

1 个答案:

答案 0 :(得分:1)

您忘记再次使用适当的subst构造函数包装ntree的结果,因此,类型系统正在尝试将d的类型与列表等同。此外,你的函数w并没有多大意义,因为你把它映射到一个ntree列表上(即k是一个ntree,你无法将它与{{1}进行比较})。

一般提示:如果您有一些奇怪的类型错误,一开始就无法理解,通常可以通过添加类型注释来缩小它们的范围,例如:关于函数参数或结果。

以下代码应该有效(未经测试):

v1

使用适量的currying并使用标准的fun subst(leaf d, v1, v2) = leaf(if d = v1 then v2 else d) | subst(node q, v1, v2) = node(map(fn k => subst(k, v1, v2), q)) 函数,它可以更简单:

map

此外,作为样式方法,最好将构造函数(fun subst v1 v2 (leaf d) = leaf(if d = v1 then v2 else d) | subst v1 v2 (node q) = node(map (subst v1 v2) q) Leaf)大写,以便于将它们与模式中的变量区分开来。