我正在尝试运行一个函数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
答案 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
)大写,以便于将它们与模式中的变量区分开来。