Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 这是Haskell代码有效吗?_List_Data Structures_Haskell_Performance - Fatal编程技术网

List 这是Haskell代码有效吗?

List 这是Haskell代码有效吗?,list,data-structures,haskell,performance,List,Data Structures,Haskell,Performance,作为初学者练习,我实现了以下函数来查找列表中的第n个元素: elem_at (h:_) 0 = h elem_at (_:t) n = elem_at t (n-1) elem_at _ _ = error "Index out of bounds" 但是,如果我在[1,2,3,4]5处调用:elem_,那么它只有在遍历整个列表之后才会返回“Index out-bounds”是否正确,以便最后一行将模式u与[]1匹配?更一般地说,如果列表很大,这不是一个性能问题吗?ghc能以某

作为初学者练习,我实现了以下函数来查找列表中的第n个元素:

elem_at (h:_) 0 = h  
elem_at (_:t) n = elem_at t (n-1)  
elem_at _ _     = error "Index out of bounds"

但是,如果我在[1,2,3,4]5处调用:elem_,那么它只有在遍历整个列表之后才会返回“Index out-bounds”是否正确,以便最后一行将模式u与[]1匹配?更一般地说,如果列表很大,这不是一个性能问题吗?ghc能以某种方式优化这种情况吗?

我相信haskell实现的效率与用任何语言遍历单个链表的效率差不多。如果数据存储在不同的结构中,则您可以回答问题,而无需遍历列表

事实上,这几乎就是索引列表的标准方法。你需要加上检查负数

elem_at xs n | n < 0 =  error "elem_at: negative index"
以及基本情况和感应情况:

elem_at (x:_)  0         =  x
elem_at (_:xs) n         =  elem_at xs (n-1)
还有列表索引的前奏定义,
(!!)
操作符


通过worker包装器可以生成稍微更高效的版本,将索引测试浮动到顶层。

我的“问题”是我非常喜欢上面的代码,因为它非常简洁。如果我可以不写更多的东西,并且在运行时仍然有非常高效的代码,那将是非常理想的。我已经编写了另一个版本,它可以更快地触发越界错误(我认为),但它没有那么优雅。如果您有一个静态列表,并且只需要快速查找,那么您可以通过将列表转换为数组来提高效率。谢谢这是有道理的。但是等等。。。从[1,2,3,4]和[5]开始,我必须使用归纳情况4次,对吗?如果n太大,你会在[]\u处找到elem_的基本情况。这很好,因为如果您将n与长度进行比较,您将遍历列表一次以获取长度,然后再次查找元素。@Tim您是对的。补充问题:Haskell是否在内部存储列表的长度,以便能够快速查询列表?否。您可以编写自己的列表,但不能使用对列表进行操作的内置函数。有人说要把列表类型变成一个typeclass,这样它就可以被泛化了,但我不认为在这方面做了什么。此外,@Don Stewart更擅长继续这一思路,所以我在这里结束。@Frank:不,列表是简单的递归类型,
data[a]=[].[a]
。就这样。如果您的算法依赖于索引或长度取值,请考虑使用手指树或向量(<代码>数据>序列<代码> >或<代码>数据>向量< /代码>。
elem_at (x:_)  0         =  x
elem_at (_:xs) n         =  elem_at xs (n-1)