![](/img/trans.png)
[英]Why does a Haskell type "deriving Integral" need to be "deriving Enum"?
[英]Why some Haskell functions does not abstract concrete integral type?
例如,函数length
抽象具体序列( Foldable
),但不抽象具体整数类型Int
:
length :: Foldable t => t a -> Int
具有以下类型签名会更有用或更方便吗?
length' :: Foldable t, Integral i => t a -> i
是的,也许吧,但是首先要注意的是,多态并不总是一件好事。 如果所有函数都具有高度多态的参数和结果,则编译器几乎没有信息可以开始类型推断,因此最终您不得不键入更加尴尬的局部签名。
现在关于length
,几乎没有理由为什么想要除Int
以外的任何其他Integral
类型的结果,至少在64位计算机上不这样:
Word16
类的较小类型在Haskell中通常不会提供太多的性能或内存优势,因为会有一些装箱操作,然后您只有一个64位的指针,只能指向16位的信息……有点傻。 Int
仅保证在某些极端情况下可以用尽29,但实际上这仅与内存和性能受到限制的32位平台有关,因此您不希望处理如此大的数据。 Foldable
(由于参数性而总是装箱)更有效。 未装箱的向量或ByteString
的性能要好得多。 Integer
或其他更昂贵的东西,而不是因为长度而已,而不仅仅是出于上下文原因,那么最好以Int
计算长度并在末尾进行一次转换,而不是将缓慢的加法运算拖累整个清单。 就是说,我确实有时希望签名实际上是已经存在的签名。
genericlength :: (Foldable t, Num i) => t a -> i
...请注意,该函数不需要知道其结果将是整数。 实际上,使结果合理是非常有用的,因此我们可以编写
average :: Fractional n => [n] -> n
average l = sum l / length l
而不需要额外的fromIntegral
。
在Prelude.length
不是这样的Prelude.length
? 我不知道,似乎颇有历史。 理由可能就像我一开始所说的那样,你不想过多的多态性 。 再说一次,IMO通常是使函数结果尽可能多态的,并且更严格地限制参数是一个好主意,因为这样,结果将始终绑定到可以用于类型推断的对象上。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.