【发布时间】:2020-04-27 12:41:57
【问题描述】:
我正在完成 Graham Hutton 的“Haskell 编程”一书中的练习,作为练习的一部分,我重新实现了 Haskell 的 last 函数,如下所示:
lasst xs = drop (length xs - 1) xs
现在这对非空列表很有效:
> lasst [1,2,3,4,5]
[5]
但是,令我惊讶的是,对于一个空列表,它返回一个空列表:
> lasst []
[]
我对此感到惊讶,因为我希望 (length []) - 1 被评估为 -1 并且随后对 drop -1 [] 的评估被抛出。
为什么我的实现会为空列表返回一个空列表,而不是抛出异常?
【问题讨论】:
-
你应该为
-1使用括号,所以drop (-1) [],否则你执行drop - 1 [],这没有多大意义。 -
如果索引为负数,则不删除任何元素。这也包含在 Haskell 报告中。
-
谢谢@willem-van-onsem。事实上,我看到来自
drop -1 []的异常是由于缺少括号。当我添加它们时,drop (-1) []根据规范返回[]。 -
这也不例外。
-
BTW
drop (length xs - 1) xs效率极低:它会遍历列表一次以获取其长度;然后再次删除前缀。更好的是直接使用模式匹配编码lasst。 (然后您可以对其进行编码以在空列表上引发异常。)
标签: haskell