【发布时间】:2018-08-18 11:38:32
【问题描述】:
我编写了以下函数来查找给定 Snoc 列表中的第 N 个元素(反向缺点),但我认为这不是问题的最佳解决方案。我想知道您是否愿意分享一些见解、代码或建议以查看不同的解决方案;您可能会考虑更有效地完成这项工作:
这是我的功能:
data ListS a = NilS
|Snoc (ListS a) a deriving Show
len :: ListS a -> Int
len NilS = 0
len (Snoc a b) = 1 + len(a)
nthElementS :: Int -> ListS a -> a
nthElementS _ NilS = error "Empty List"
nthElementS n s = if n < 0 || n >= len(s) then error "Invalid Index"
else nthAux ((len(s)-1)-n) s where
nthAux 0 (Snoc a b) = b
nthAux m (Snoc a b) = nthAux (m-1) a
一些例子:
Main> nthElementS 0 (Snoc (Snoc (Snoc (Snoc (Snoc NilS 1) 2) 3) 4) 5)
1
Main> nthElementS 2 (Snoc (Snoc (Snoc (Snoc (Snoc NilS 1) 2) 3) 4) 5)
3
作为附加询问:实现连接 2 个 Snoc 列表的函数的最佳方法是什么?我已经在考虑一个解决方案,但它需要一个辅助函数来跟踪第 N 个位置,而且我觉得这不会充分利用 Haskell 相对于其他语言的优势。
提前致谢。
【问题讨论】:
-
您的类型与常规的 cons 列表同构。有了它,你的函数实际上是
nthFromEnd。与列表一起保持列表的长度将使实施变得微不足道。否则,只需从反转列表中取出第 n 个元素,或者使用foldr进行等效计算,融合反转和长度测量(与答案中的代码不同)。至于 O(1) 附加,你可以例如使用a different data type 表示列表。 -
谢谢你,Will Ness,我也从没想过要应用 foldr。很棒的建议。
标签: haskell