问题描述
我的老师最近遍历了ML中使用“ let”和“ in”的函数,但是该函数的主体对我感到困惑,因为我不了解它们是如何协同工作以产生结果的。该功能获取您花园中的蔬菜列表,并用给定的替代品替换原始蔬菜,这样该列表将在原始元素所在的每个位置打印出替代品。此功能
fun replacevegetable(orig,subt,Garden([]) = Garden([])
| replacevegetable(orig,Garden([first::rest]) =
let val Garden(newRest) =
replacevegetable(orig,subst,Garden(rest));
in Garden((if first = orig then subst else first)::newRest)
end
| replacevegetable(orig,x) = x;
我不担心最后一个模式“ replacevegetable(orig,subst,x)= x;”,主要关注理解第二个模式。我想我知道Garden(newRest)是该函数的局部变量,并且无论replacevegetable(orig,subst,Garden(rest))产生什么,都将存储在该局部变量中。我不完全知道“在Garden((如果先是= orig,然后先是其他,然后先替代):: newRest)”上会发生什么,这是否是应用递归,因此它可以遍历列表,让我看一下它在哪里必须替换为替代品?如果是这样,我就无法确切地看到它的功能,因为整个函数让我很困惑。
解决方法
let
,in
和end
并存; in Garden((if first ...
不是“语言单元”,也没有任何意义。
以简单的形式,
let val x = y in e end
表示“在表达式'e'中,'x'与'y'具有相同的值。
如果该函数仅列出一个简单列表,则可能更易于理解:
fun replaceVegetable(orig,subst,[]) = []
| replaceVegetable(orig,first::rest) =
let val newRest =
replaceVegetable(orig,rest)
in (if first = orig then subst else first)::newRest
end
| replaceVegetable(orig,x) = x;
第二种情况与
完全相同| replaceVegetable(orig,first::rest) =
(if first = orig then subst else first)::(replaceVegetable(orig,rest))
您的函数还具有模式匹配绑定,而不是普通变量绑定。
let val Garden newRest = replaceVegetable(...)
in ...
end
与递归结果匹配,并将“包装”列表绑定到newRest
。
它的含义与
case replaceVegetable (...) of
Garden newRest => ...