在序言中,head具有以下签名:head :: [a] -> a
使其在空白列表上不安全,这不好! (head :: [a] -> Maybe a
是个好方法:-))
这适用于列表中的其他几个函数:last,tail,init最小值,maximum,cycle,last,init,foldl1,cycle ...实际上有许多调用errorEmptyList
>
用他的website引用 Stephen Diehl :
“ Safe提供了许多各种部分功能的Maybe版本 (头,尾)默认情况下出厂。在Maybe中包装它是 被广泛认为是正确的方法,如果设计了Haskell 今天,它们将不存在。”
我很希望看到这些不安全的函数以某种约定标记,至少是因为我不认为我们中的任何人都喜欢在生产中出现异常时爆炸:-)
是什么导致社区无法在序幕中解决这些问题?
答案 0 :(得分:5)
社区一直在通过Hack分发的 custom 前言中解决此问题。 但这不能解决前奏本身,这取决于负责Haskell的委员会。对于向后兼容的问题,从未修复过。
(我个人更喜欢Relude的方法。此前奏的head
函数的键入为NonEmpty a -> a
。)
答案 1 :(得分:3)
真正的问题是,为什么一个功能head
完全 。使用列表不需要此功能。要用(x:_)
和[]
区分大小写,就像“安全头”所允许的那样,最好的选择是只使用模式匹配或合适的高阶函数/镜头操作符。
在实践中,head
的唯一用途是当您处于某个大型函数中时,想要在列表xs
(包括许多其他参数)的顶部,您已经在其中检查它是非空的,例如因为其他一些条款已经涵盖了这一点。在这种情况下,安全性将是多余的。
可以说,这仍然是一个难题,最好用模式匹配来表达。但是关键是,不安全的打印头至少具有一些丑陋但实用的用途,而安全的打印头通常会在模式匹配中增加额外的噪声,无论如何都需要这样做。
IMO,head
,tail
和!!
应该被弃用,而不要更改。他们不断吸引来自Python等的初学者,以为他们需要这样的功能,但实际上,这种风格与Haskell的本质背道而驰。