My teacher recently went over a function in ML that uses "let" & "in" but the body of the function is confusing to me as I dont understand how they work together to produce the result. The function takes a list of vegetables in your garden and replaces an original vegetable with a given substitute, so that list will print out the substitute in every location where the original element is in.This is the function
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;
Im not worried about the last pattern "replaceVegetable(orig, subst, x) = x;", im mainly concerned about understanding the second pattern. I think I understand that Garden(newRest) is a local variable to the function and that whatever replaceVegetable(orig, subst, Garden(rest)) produces will be stored in that local variable. I dont exactly know what happens on "in Garden((if first = orig then subst else first)::newRest)" is this applying recursion so it can run through the list I give it to see where it has to replace the original with the substitute? If so, I can't exactly see how its doing that as the function as a whole is confusing for me to look at.
let
,in
, andend
go together;in Garden((if first ...
is not a "unit of language" and doesn't mean anything.In the simpler form,
means "in the expression 'e', 'x' has the same value as 'y'.
If the function took just a plain list, it might be easier to understand:
The second case here is exactly the same as
Your function also has a pattern-matching binding instead of a plain variable binding.
matches on the result of the recursion and binds the "wrapped" list to
newRest
.It means exactly the same as