类型fromIntegral是(Num b, Integral a) => a -> b.我想了解这是怎么可能的,代码是什么,可以根据需要将任何积分数转换为任何数字类型.
在实际代码为fromIntegral被列为
fromIntegral = fromInteger . toInteger
Run Code Online (Sandbox Code Playgroud)
该代码为fromInteger正在instance Num Int和instance Num Integer它们分别是:
instance Num Int where
...
fromInteger i = I# (integerToInt i)
Run Code Online (Sandbox Code Playgroud)
和
instance Num Integer where
...
fromInteger x = x
Run Code Online (Sandbox Code Playgroud)
假设I#调用一个C程序将一个转换Integer为一个Int我没有看到这些中的任何一个生成结果,例如,可以添加到a Float.他们如何去往Int或Integer去别的什么?
fromInteger将嵌入一个表达式,该表达式要求它生成某种类型.它无法知道所需的类型是什么?那会发生什么?
谢谢.
Ben*_*Ben 11
因为fromInteger是Num类的一部分,所以每个实例都有自己的实现.这两个实现(for Int和Integer)都不知道如何制作a Float,但是当你使用fromInteger(或fromIntegral)制作a 时它们不会被调用Float; 这就是Float实例的Num用途.
等等所有其他类型.没有一个地方知道如何将整数转换成任何Num类型; 这是不可能的,因为它必须支持Num尚不存在的用户定义的实例.相反,当每个单独的类型被声明为Num一种方法的实例时,必须提供该特定类型(通过实现fromInteger).
fromInteger将嵌入一个表达式,该表达式要求它生成某种类型.它无法知道所需的类型是什么?那会发生什么?
其实,知道它的预期,从呼叫嵌入表达式返回什么类型是究竟它是如何工作的.
Haskell中的类型检查/推断一次在两个"方向"上工作.它自上而下,找出每个表达式应该具有的类型,以便适应它正在使用的更大的表达式.它也是"自下而上",找出每个表达式应该具有哪个类型来自较小的子表达式 - 它是由它构建的表达式.当它找到一个不匹配的地方时,就会出现类型错误(这就是你在类型错误消息中看到的"期望类型"和"实际类型"的确切位置).
但是因为编译器具有每个表达式的自上而下的知识("期望类型"),所以它完全能够确定fromInteger在Float预期的地方使用调用,因此在该调用中使用Float实例Num.
类型类与 OOP 接口的区别之一是类型类可以分派方法的结果类型,而不仅仅是其参数的类型。典型的例子就是read :: Read a => String -> a函数。
fromInteger有类型fromInteger :: Num a => Integer -> a. 根据 的类型选择实现a。如果类型检查器知道这a是 a Float,则将使用 的Num实例,而不是或的实例。FloatIntInteger