SML - 列表替换函数的迭代翻译
我相信我在将第一个函数转换为仅使用赋值和循环方面处于正确的轨道上。我知道这违背了函数式编程,但这是教授想要的。
递归函数:
fun sub (x, y, []) = []
| sub (x, y, z::zz) = if x = z then y::sub(x, y, zz)
else z::sub(x, y, zz);
迭代翻译:
fun sub2 (x, y, z) =
let val ret = ref []; val temp = z;
in
while !temp <> []
do (if x = hd(!temp) then ret := !ret::y; temp := tl(!temp)
else ret := ret::hd(!temp); temp := tl(!temp));
!ret;
end;
我在 smlnj 上运行时收到以下错误。第一个在 do 线上,第二个在最后。
错误:语法错误:将 END 替换为 EQUALOP
错误:在 EOF 处发现语法错误
我希望能帮助调试,或者也许有一种更干净的方法来完成此迭代函数。
I believe I'm on the right track in converting my first function to only use assignments and loops. I know this is against functional programming, but it's what a professor wants.
Recursive function:
fun sub (x, y, []) = []
| sub (x, y, z::zz) = if x = z then y::sub(x, y, zz)
else z::sub(x, y, zz);
Iterative translation:
fun sub2 (x, y, z) =
let val ret = ref []; val temp = z;
in
while !temp <> []
do (if x = hd(!temp) then ret := !ret::y; temp := tl(!temp)
else ret := ret::hd(!temp); temp := tl(!temp));
!ret;
end;
I receive the following errors running on smlnj. The first on the line with the do, and second being at the end.
Error: syntax error: replacing END with EQUALOP
Error: syntax error found at EOF
I'd appreciate help debugging or perhaps a cleaner way to accomplish this iterative function.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为什么哦为什么他不想要那个?没关系...
有很多问题。
!temp <> null
将进行限制。使用 List.null 函数代替。!ret;
处的分号不应该出现,否则end
将成为序列的一部分,从而失败。ret
。'a * 'a list
,因此采用一个元素,然后采用一个元素列表。解决此问题并仍然保留元素顺序的一种方法是使用追加 (@) 函数,然后将要追加的元素放置在单例列表中。然而,有很多方法可以更好地处理这个问题,因为追加函数在大列表上的表现非常差。以下是一个有效的函数:
这里可以改进的一个明显的事情是您始终使用相同的值更新 temp。所以这个可以排除掉。并且条件可以改为 case
特别注意元素如何不附加而是添加到结果列表中,而是放置在前面,然后在最后将结果列表反转以获得正确的顺序。这将使您在大型列表上获得更好的性能。然而,当您在 SML 中采用命令式风格时,还有更好的方法可以做到这一点。
正如您已经看到的,它可以通过函数式方式完成。但它也可以做得更简单。使用地图考虑以下内容。
Why oh why would he ever wan't that? Never mind...
There are quite a few problems.
!temp <> null
will make the restriction. It would be "best practice" to use the List.null function instead.!ret;
should not be there as your sequence stops, elseend
will become part of the sequence which will fail.ret
in you else part of the condition.'a * 'a list
and thus takes an element and then a list of elements. One way of fixing this and still preserving the order of elements is to use the append (@) function and then placing the element to append in a singleton list. However there are so many ways of handling this in a better way as the append function performs very poorly on big lists.Following is a function that works:
One obvious thing that can be improved here is that you always update temp with the same value. So this could be factored out. And the condition could be changed to a case instead
Especially notice how the elements are not appended but to the resulting list, but placed in the front and then at the end the resulting list is reversed to get the correct order. This will give you much better performance on big lists. There are however still better ways of doing this when you go imperative style in SML.
As you have already seen, it can be done in a functional way. But it could also be done simpler. Consider the following using map.