在 Eiffel 中,允许使用不从堆中分配的扩展类。从开发人员的角度来看,很少需要考虑从 Int 到 Float 的转换,因为它是自动的。我的问题是:为什么 Haskell 没有选择类似的方法来建模 Num。具体来说,让我们考虑 Int 实例。这是我提出问题的理由:
[1..3] = [1,2,3]
[1..3.5] = [1.0,2.0,3.0,4.0] -- rounds up
第二个列表是我没想到的,因为根据定义,在任何两个整数之间都有无限的浮点数。当然,一旦我们测试了这个序列,很明显它会返回四舍五入的浮点数的底数。需要这些转换的原因之一是允许我们计算一组整数的平均值。
在 Eiffel 中,数字类型层次结构对程序员更友好一些,并且可以根据需要进行转换:例如,创建一个序列仍然可以是一组导致浮点均值的 Ints。这具有可读性优势。
扩展类没有在 Haskell 中实现是有原因的吗?任何参考都会有很大帮助。
@ony:关于并行策略的要点:使用原语时我们不会面临同样的问题吗?该手册确实不鼓励使用原语,这对我来说一般来说是有意义的,只要我们可以使用原语,我们可能需要使用抽象类型。我在尝试对数字求平均值时遇到的问题是缺少 Fractional Int 实例,以及为什么 5/3 不提升为浮点而不是创建浮点数组来获得相同的结果。为什么没有定义 Int 和 Integer 的 Fractional 实例一定是有原因的?这可以帮助我更好地理解其中的原理。
@leftroundabout:问题不在于扩展类本身,而是此类功能可以提供的便利性,尽管仅该功能不足以处理从 int 浮动的类型提升,例如我在对@ony 的回复中提到的。让我们以均值的经典示例为例,尝试将其定义为
> [Int] :: Double
let mean xs = sum xs / length xs (--not valid haskell code)
[Int] :: Double
let mean = sum xs / fromIntegral (length xs)
如果我不必调用 fromIntegral 来使 mean 函数工作并且与缺少的Fractional Int相关联,我会喜欢它。虽然解释似乎有道理,但它必须,我不明白的是,如果我清楚我期望一个 double 并且我在我的类型签名中声明它是否不足以进行适当的转换?