作为初学练习,我已经实现了以下函数来查找列表中的第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 out of bounds”是正确的,以便最后一行与模式匹配_ _与[] 1?更一般地说,如果列表是 big 那么这不是性能问题吗? ghc可以以某种方式优化这种情况吗?
答案 0 :(得分:4)
事实上,这正是索引列表的规范方法。您需要添加检查负数
elem_at xs n | n < 0 = error "elem_at: negative index"
您可以为空列表添加特定匹配项:
elem_at [] _ = error "elem_at: index too large"
基础和归纳案例:
elem_at (x:_) 0 = x
elem_at (_:xs) n = elem_at xs (n-1)
你已经得到了列表索引的Prelude定义,即(!!)
运算符。
通过worker包装器可以产生稍高效的版本,将索引测试浮动到顶层。
答案 1 :(得分:2)
我相信haskell实现与遍历任何语言的单链表一样高效。如果数据存储在不同的结构中,那么您可以在不遍历列表的情况下回答问题。