GHCi中fromIntegral的行为不一致

时间:2012-07-11 18:35:59

标签: haskell types ghci

当我使用fromIntegral函数时,我希望有人可以在GHCi中解释以下行为:

Prelude> let x = 1 :: Integer                                                                                                                                                    
Prelude> :t x                                                                                                                                                                    
x :: Integer                                                                                                                                                                     
Prelude> sqrt $ fromIntegral x                                                                                                                                                   
1.0                                                                                                                                                                              
Prelude> let y = fromIntegral x                                                                                                                                                  
Prelude> sqrt y                                                                                                                                                                  

<interactive>:181:1:                                                                                                                                                             
No instance for (Floating Integer)                                                                                                                                           
  arising from a use of `sqrt'                                                                                                                                               
Possible fix: add an instance declaration for (Floating Integer)                                                                                                             
In the expression: sqrt y                                                                                                                                                    
In an equation for `it': it = sqrt y                                                                                                                                         

为什么我设置y然后选择sqrt或直接选择sqrt

1 个答案:

答案 0 :(得分:9)

fromIntegral的返回类型是多态的。因此,代码中y的类型可能会为Num a => a。这种类型允许您使用y作为sqrt的参数而没有问题。

然而,由于单态性限制,y的类型不允许是多态的。因此,它默认为默认的Num类型,即Integer

执行sqrt $ fromIntegral x时,单态限制不适用,因为它仅适用于全局变量,并且此次不会将fromIntegral的结果存储在变量中。

您可以通过向y(let y :: Num a => a; y = fromIntegal x)添加类型签名或禁用单态限制来解决此问题。