我在下面声明了函数,希望如果我要覆盖列表中的某些元素,它实际上可以工作。但我不完全确定这是否是正确的方法。任何与我不同的想法将不胜感激
fun foo (ls,n) =if ls = nil then nil else ( rev ( 1::List.rev ( List.take (ls,n-1 ))))@(List.drop (ls,n)
它应该像这样工作
foo ([0,3,9],2) = [0,1,9]
(此代码的右括号太少。
我认为这种方法没有任何大问题,特别是如果您想避免编写自己的显式递归解决方案。我认为如果您将新值添加到第二部分的开头而不是第一部分的结尾,则不需要做太多的反转。如果你编写自己的函数,你可以避免一些重复的工作。您可能想查看 List.revAppend
,它适用于此类情况。
作为附带评论:列表对于随机位置的更新来说并不是一个特别好的数据结构。
你在那里做了很多不必要的工作。 take
、drop
、rev
和@
都涉及遍历列表 - 你最终会这样做五次,而你只需要这样做一次。正如 Jeffrey 指出的那样,您只需将1
附加到 drop
的结果中即可消除rev
调用,但仍有改进的余地。
您应该尝试编写自己的递归函数,该函数不依赖于List
库中的任何内容。你真的需要培养对递归思维的直观掌握,才能通过函数式编程到达任何地方。调用顺序应如下所示:
foo ([a,b,c,d], 4)
= a :: foo([b,c,d], 3)
= a :: b :: foo([c,d], 2) ...