我不明白:t for forIntegral

时间:2014-04-19 09:45:24

标签: haskell numbers

LYAHfromIntegral描述为:

  

从它的类型签名中我们看到它需要一个整数并将其转换为更一般的数字。当您希望积分和浮点类型很好地协同工作时,这非常有用。

我根本不了解这个功能是如何工作的,或者为什么需要使用解释器。

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?

5 个答案:

答案 0 :(得分:10)

fromIntegral :: (Integral a, Num b) => a -> b

需要一个arg。 =>应该被理解为具有普遍量化的逻辑含义:

  

适用于所有类型ab

     
    

如果aIntegral的实例且bNum的实例,

         

然后fromIntegral可以使用a并生成b

  

此函数将类型aIntegral类型)的值转换为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。由于FractionalNum的子类,因此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不是IntInteger,而是多态Num值。放置在复杂表达式中时,它会获得适合其周围环境的类型。给出:

Prelude> :t 3.2
3.2 :: Fractional a => a
Prelude> :t (+)
(+) :: Num a => a -> a -> a

4中的4 + 3.2Fractional的{​​{1}}限制,因此:

3.2

如果程序中的其他位置没有其他限制,则多态Prelude> :t 4 + 3.2 4 + 3.2 :: Fractional a => a 值将默认为Fractionalthis question的答案给出了这种违约的简要解释。

答案 4 :(得分:2)

fromIntegral会将整数值(例如Int)转换为更一般的值,即。{。{1}}。

例如,Num a不会输入检查,但(4 :: Int) + 3.2会正常工作。