0

我的老师最近检查了 ML 中使用“let”和“in”的函数,但函数的主体让我感到困惑,因为我不明白它们如何协同工作以产生结果。该函数获取花园中的蔬菜列表,并用给定的替代品替换原始蔬菜,因此该列表将在原始元素所在的每个位置打印出替代品。这就是函数

图像到功能代码

fun replaceVegetable(orig, subt, Garden([]) = Garden([])

  | replaceVegetable(orig, subt, 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, subst, x) = x;

我不担心最后一个模式“replaceVegetable(orig, subst, x) = x;”,我主要关心理解第二个模式。我想我知道 Garden(newRest) 是函数的局部变量,并且无论 replaceVegetable(orig, subst, Garden(rest)) 产生什么都将存储在该局部变量中。我不完全知道“in Garden((if first = orig then subst else first)::newRest)”上会发生什么,这是应用递归,所以它可以遍历我给它的列表,看看它必须在哪里替换原来的替代品?如果是这样,我无法确切地看到它作为一个整体的功能是如何做到的,这让我很困惑。

4

1 回答 1

0

let, in,end一起去; in Garden((if first ...不是“语言单位”,也没有任何意义。

以更简单的形式,

let val x = y in e end

意思是“在表达式‘e’中,‘x’与‘y’具有相同的值。

如果该函数只使用一个简单的列表,则可能更容易理解:

fun replaceVegetable(orig, subst, []) = []
  | replaceVegetable(orig, subst, first::rest) =
    let val newRest  = 
            replaceVegetable(orig, subst, rest)
    in (if first = orig then subst else first)::newRest
    end
  | replaceVegetable(orig, subst, x) = x;

这里的第二种情况与

| replaceVegetable(orig, subst, first::rest) =
      (if first = orig then subst else first)::(replaceVegetable(orig, subst, rest))

您的函数还具有模式匹配绑定,而不是普通变量绑定。

let val Garden newRest = replaceVegetable(...)
in ...
end

匹配递归结果并将“包装”列表绑定到newRest.
意思是完全一样的

case replaceVegetable (...) of
     Garden newRest => ...
于 2020-09-22T07:39:10.493 回答