在 Haskell 中实现以线性时间运行的反向操作
我刚刚学习 Haskell,如果我的问题很愚蠢,我很抱歉。我正在阅读 learnyouahaskell.com,现在正在读第 5 章“递归”。有一个标准“反向”函数的实现示例:
reverse' :: [a] -> [a]
reverse' [] = []
reverse' (x:xs) = reverse' xs ++ [x]
但它似乎在 O(N^2) 时间内运行,而标准反向在 O(N) 时间内运行(我希望如此)。下面的代码说明了这一点:
sum (reverse [1,2..1000000]) -- runs pretty fast
sum (reverse' [1,2..1000000]) -- never finishes
因此,我开始思考如何更快地实现我自己的反向操作。用命令式语言很容易做到这一点。也许我需要后续章节中的一些更高级的材料来做到这一点?欢迎任何提示。
I'm just learning Haskell, so sorry if my question is stupid. I'm reading learnyouahaskell.com and now I'm at chapter 5 "Recursion". There's an example of implementation of standard 'reverse' function:
reverse' :: [a] -> [a]
reverse' [] = []
reverse' (x:xs) = reverse' xs ++ [x]
But it seems that it runs in O(N^2) time, while the standard reverse runs in O(N) (I hope so). The following code illustrates this:
sum (reverse [1,2..1000000]) -- runs pretty fast
sum (reverse' [1,2..1000000]) -- never finishes
So, I started thinking how to implement my own reverse faster. It's pretty easy to do in imperative languages. Maybe I need some more advanced material from subsequent chapters to do this? Any hints are welcomed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
它可以使用额外的累加器参数来高效实现,例如本例中
fac
的第二个参数:如果您只是想知道它在标准库中是如何完成的,您也可以 查看源代码。
It can be implemented efficiently using an extra accumulator parameter, like the second parameter of
fac
in this example:If you just want to know how it's done in the standard library, you can also look at the source code.
reverse
在 前奏。您可以将其实现为:
reverse
is defined in the Prelude.You can implement it as:
其运行时间为 O(n)。这个想法非常简单 - 您采用一个空列表(累加器)并从上到下将元素传输到其中。
This runs in O(n). The idea is pretty simple - you take an empty list(accumulator) and transfer elements to it from top to bottom.