如何从整体工作?

时间:2016-11-22 21:14:29

标签: haskell

fromIntegral的类型为(Num b, Integral a) => a -> b。我想了解这是怎么可能的,代码是什么,可以根据需要将任何积分号转换为任何数字类型。

fromIntegral的{​​{3}}列为

fromIntegral = fromInteger . toInteger

fromInteger actual code位于instance Num Intinstance Num Integer下,分别为:

instance  Num Int  where
  ...
  fromInteger i = I# (integerToInt i)

instance  Num Integer  where
  ...
  fromInteger x  =  x

假设I#调用了一个将Integer转换为Int的C程序,我不知道其中任何一个生成的结果可能会添加到Float。他们如何从IntInteger转到其他地方?

fromInteger将嵌入到一个表达式中,该表达式要求它生成某种类型。它无法知道所需的类型是什么?那会发生什么?

感谢。

2 个答案:

答案 0 :(得分:11)

因为fromIntegerNum类的一部分,所以每个实例都有自己的实现。 两个实现(IntInteger)中的都不知道如何制作Float,但是当你'时,它们不会被调用。重新使用fromInteger(或fromIntegral)制作Float;那是Float Num实例的用途。

等等所有其他类型。没有一个地方知道如何将整数转换为任何Num类型;这是不可能的,因为它必须支持尚未存在的用户定义的Num实例。相反,当每个单独的类型被声明为Num的实例时,必须提供的特定类型的(通过实现fromInteger)。

  

fromInteger将嵌入到一个表达式中,该表达式要求它生成某种类型。它无法知道所需的类型是什么?那会发生什么?

实际上,知道它希望从嵌入调用的表达式返回的类型是完全它是如何工作的。

Haskell中的类型检查/推理在两个"方向上工作"立刻。它自上而下,弄清楚每个表达式应该具有什么类型,以便适应它所使用的更大的表达。它还可以自下而上"自下而上& #34;,确定每个表达式应该从它构建的较小子表达式中具有什么类型。当它找到一个不匹配的地方时,就会出现类型错误(确切地说"预期类型""实际类型"你看到的输入错误消息来自)。

但是因为编译器对每个表达式都有自上而下的知识("期望的类型"),所以它完全能够发现fromInteger的调用正在进行在需要Float的位置使用,因此在该调用中使用Float Num实例。

答案 1 :(得分:3)

将类型类与OOP接口区分开来的一个方面是类型类可以在方法的 result 类型上调度,而不仅仅是在其参数的类型上。典型的例子是read :: Read a => String -> a函数。

fromInteger的类型为fromInteger :: Num a => Integer -> a。根据{{​​1}}的类型选择实现。如果类型检查员知道aa,则会使用Float的{​​{1}}实例,而不是NumFloat的实例