【发布时间】:2021-08-21 20:03:37
【问题描述】:
我正在研究 99 个 Haskell 问题并尝试使用这段代码来解决第二个问题,这需要返回数组的倒数第二个元素:
myPen :: [a] -> a
myPen [] = error "Empty lists have no penultimate element."
myPen list@(_:xs)
| length list == 1 = error "Lists size 1 have no penultimate element."
| length xs == 2 = head xs
| otherwise = myPen xs
这段代码可以编译,但是当给定输入时
myPen [1,2]
它会产生错误
*** Exception: Lists size 1 have no penultimate element.
CallStack (from HasCallStack):
error, called at prob1_10.hs:16:25 in main:Main
据我了解,@ 在这种情况下应该允许引用整个列表,但它似乎只引用了xs 或列表的尾部。
This 似乎支持它应该包括x 和xs 的论点。
我的问题有两个:
1.) 为什么会这样? 2.) 引用整个列表的正确方法是什么?
【问题讨论】:
-
第一个守卫都不是真的,因为
length list是2,而length xs是1。注意xs是列表的tail,所以列表没有第一个元素。 -
“倒数第二个”的意思是“倒数第二个”,因此是
myPen。不过,只是为了清楚起见而进行了编辑。 -
length在这种情况下(在警卫中)应不惜一切代价避免。它完全不必要地破坏了惰性,并在有限列表上引入了二次行为,并在无限列表上引入了分歧。 -
@WillNess 我会进一步说,初学者永远不应该永远使用
length、!!或head。 -
@leftaroundabout 是的,...除非在实现一些计数时。或实际上采取了一些东西。 :) 那么,我们应该说,“几乎总是”?
标签: haskell