考虑这些(或多或少)等效类型签名:
f1 :: [a] -> Int -> a
f2 :: Integral b => [a] -> b -> a
f2 比 f1 更通用,这是一个很大的优势,但 f1 优于 f2
似乎在H-99问题的解决方案中,以及许多Project Euler问题的解决方案中, f1 形式比 f2
我不确定为什么。是简单的程序员懒惰,还是使用更通用的版本( f2 )会有性能成本,还是有其他原因?
答案 0 :(得分:8)
通常这是因为人们希望将积分与length
的结果以及已经约束到Int
的其他函数结合使用。虽然常常有generic
*个函数,例如genericLength
,但这些名称较长,而不在序言中。
Int
的效果更容易理解。 Integral a
的效果在很大程度上取决于函数是否专门用于Integral
的特定实例。
Int
通常不仅足够而且诚实。例如,严格的ByteString
s不能超过Int
大小(通常,请不要用深奥的例子评论)假设您的编译器使用机器字或更大的Int
而不是愚蠢的标准29+ bits。
过度使用类型类会使签名变得混乱,使语言的可读性降低。如果极端泛化变得普遍,特别是对于原始函数,我认为我们需要找到一种更简洁的方式来表达限制,以避免让程序员疯狂。