LYAH将fromIntegral
描述为:
从它的类型签名中我们看到它需要一个整数并将其转换为更一般的数字。当您希望积分和浮点类型很好地协同工作时,这非常有用。
我根本不了解这个功能是如何工作的,或者为什么需要使用解释器。
fromIntegral 4 + 3.2
7.2
4 + 3.2
7.2 -- seems to work just fine?!
fromIntegral 6
6
fromIntegral 6.2
-- raises an error
:t fromIntegral
fromIntegral :: (Integral a, Num b) => a -> b -- does this mean it takes 1 arg or 2?
答案 0 :(得分:10)
fromIntegral :: (Integral a, Num b) => a -> b
需要一个arg。 =>
应该被理解为具有普遍量化的逻辑含义:
适用于所有类型
a
和b
,如果
a
是Integral
的实例且b
是Num
的实例,然后
fromIntegral
可以使用a
并生成b
。
此函数将类型a
(Integral
类型)的值转换为b
类型(更一般的Num
类的实例) 。例如。你不能将整数1
添加到Haskell中的float 2
而不转换前者:
Prelude> (1 :: Int) + (2 :: Float)
<interactive>:10:15:
Couldn't match expected type `Int' with actual type `Float'
In the second argument of `(+)', namely `(2 :: Float)'
In the expression: (1 :: Int) + (2 :: Float)
In an equation for `it': it = (1 :: Int) + (2 :: Float)
Prelude> fromIntegral (1 :: Int) + (2 :: Float)
3.0
答案 1 :(得分:3)
:t fromIntegral
fromIntegral :: (Integral a, Num b) => a -> b
这意味着它接受输入类型a
的一个参数并返回另一个类型为b
的参数。类约束仅表示a
类型必须是Integral
类型类的实例,b
类型必须是Num
类型类的实例。所以fromIntegral
实际上将整数类型转换为更一般的类型。这在许多转换中都很有用。
关于fromIntegral
的用例,这个例子将清楚地表明:
λ> :t (/)
(/) :: Fractional a => a -> a -> a
λ> let a = 3 :: Int
λ> a / 4.2
<interactive>:62:3:
No instance for (Fractional Int) arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Int)
In the expression: a / 4.2
In an equation for `it': it = a / 4.2
λ> fromIntegral a / 4.2
0.7142857142857143
或者举个例子:
λ> let a = 3 :: Int
λ> a + 4.2
<interactive>:5:5:
No instance for (Fractional Int) arising from the literal `4.2'
Possible fix: add an instance declaration for (Fractional Int)
In the second argument of `(+)', namely `4.2'
In the expression: a + 4.2
In an equation for `it': it = a + 4.2
λ> fromIntegral a + 4.2
7.2
答案 2 :(得分:2)
fromIntegral
签名的限制:
fromIntegral :: (Integral a, Num b) => a -> b
表示参数类型a
必须是Integral
类的实例,而结果类型b
是任何Num
实例。
fromIntegral 6.2
无法输入检查,因为6.2
不是Integral
的实例。
4 + 3.2
有效,因为(+)
的类型为Num a => a -> a -> a
,而3.2
的类型为Fractional a => a
。由于Fractional
是Num
的子类,因此GHC已为表达式Fractional a => a
推断出4 + 3.2
的类型。
答案 3 :(得分:2)
这是否意味着需要1个arg或2个?
要回答这个问题,请先注意=>
和->
是不同的。然后,只查看=>
:
a -> b
具有这种类型的函数只有一个参数,fromIntegral
也是如此。在左侧=>
,您找不到参数,但类型约束。如果fromIntegral
的类型为a -> b
,则它将采用任何类型的参数并生成任何其他类型的结果。 (Integral a, Num b)
约束限制了类型,因此参数的类型必须是Integral
类的实例(即,参数必须是整数),结果必须是Num
的实例(也就是说,结果必须是某种数字)。
只要有整数,就需要fromIntegral
,并且需要将它与需要非整数数字参数的函数一起使用。一个简单的示例是将Integer
添加到Double
。但是,如果没有fromIntegral
?
Prelude> 4 + 3.2
7.2
答案在于文字:
Prelude> :t 4
4 :: Num a => a
4
不是Int
或Integer
,而是多态Num
值。放置在复杂表达式中时,它会获得适合其周围环境的类型。给出:
Prelude> :t 3.2
3.2 :: Fractional a => a
Prelude> :t (+)
(+) :: Num a => a -> a -> a
4
中的4 + 3.2
受Fractional
的{{1}}限制,因此:
3.2
如果程序中的其他位置没有其他限制,则多态Prelude> :t 4 + 3.2
4 + 3.2 :: Fractional a => a
值将默认为Fractional
。 this question的答案给出了这种违约的简要解释。
答案 4 :(得分:2)
fromIntegral
会将整数值(例如Int
)转换为更一般的值,即。{。{1}}。
例如,Num a
不会输入检查,但(4 :: Int) + 3.2
会正常工作。