这个 Haskell 代码高效吗?
作为初学者练习,我实现了以下函数来查找列表中的第 n 个元素:
elem_at (h:_) 0 = h
elem_at (_:t) n = elem_at t (n-1)
elem_at _ _ = error "Index out of bounds"
但是,如果我调用: elem_at [1,2,3,4] 5,它返回“Index”是否正确?出界”仅在遍历整个列表后,以便最后一行与模式 _ _ 与 [] 1 匹配?更一般地说,如果列表很大,那不是性能问题吗? ghc 能以某种方式优化这种情况吗?
As a beginner exercise, I've implemented the following function to find the n-th element in a list:
elem_at (h:_) 0 = h
elem_at (_:t) n = elem_at t (n-1)
elem_at _ _ = error "Index out of bounds"
However, if I call: elem_at [1,2,3,4] 5, is it correct that it will return "Index out of bounds" only after having traversed the whole list, so that the last line matches the pattern _ _ with [] 1? More generally, if the list were big wouldn't that be a performance issue? Can ghc somehow optimize that situation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
事实上,这几乎正是索引列表的规范方式。您需要添加对负数的检查
并且您可以为空列表添加特定的匹配:
以及基本和归纳案例:
并且您已经获得了列表索引的 Prelude 定义,
(!!) 运算符。
可以通过工作包装器生成稍微更高效的版本,将索引测试浮动到顶层。
In fact, this is precisely the canonical way to index a list, almost. You need to add in checking for negative numbers
And you could add a specific match for the empty list:
And the base and inductive case:
and you've got the Prelude definition of list indexing, the
(!!)
operator.A slightly more efficient version can be yielded via the worker wrapper, floating the index test to the top level.
我相信 haskell 实现的效率与任何语言中遍历单链表的效率差不多。如果数据存储在不同的结构中,那么您无需遍历列表即可回答问题。
I believe that the haskell implementation is about as efficient as traversing a singly-linked list in any language. If the data were stored in a different structure, then the you could answer the question without traversing the list.