理解为什么A/B不工作,但fromInteger A/fromInteger B则
在Haskell,这个工程:理解为什么A/B不工作,但fromInteger A/fromInteger B则
ghci>5/2
2.5
大。但如果我分配5和2变量..
Main> let a = 5
Main> let b = 2
Main> a/b
<interactive>:68:2:
No instance for (Fractional Integer)
arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Integer)
In the expression: a/b
In an equation for `it': it = a/b
Main>
我得到错误了wazoo。我能解决的唯一方法是说:
*Main> fromInteger a/fromInteger b
2.5
*Main>
fromInteger发生了什么事?为什么我需要它来完成这项工作?
Prelude> :t 5/2 -- The type is inferred to be a fractional
5/2 :: Fractional a => a
Prelude> :t (/) -- ...because the type of (/)
(/) :: Fractional a => a -> a -> a
Prelude> let x = 5
Prelude> let y = 2
Prelude> :t x -- In GHC there are addditional type defaulting rules
x :: Integer -- Instead of Num a => a, a lone integral is typed as `Integer`
Prelude> :t y
y :: Integer
Prelude> :i Fractional -- Notice that 'Integer' is not an instance of 'Fractional'
class Num a => Fractional a where
(/) :: a -> a -> a
recip :: a -> a
fromRational :: Rational -> a
-- Defined in `GHC.Real'
instance Fractional Float -- Defined in `GHC.Float'
instance Fractional Double -- Defined in `GHC.Float'
简而言之? GHCi类型 - 默认您的允许变量为Integer
,它没有Fractional
实例(因为Integer
s不是分数)。在通过ghc编译的Haskell程序中,类型将会统一起来。
编辑:我应该补充一点,我试图说明如何将let x = 4
推断为Double在更大的背景下,而不是GHCi。为了回应哈马尔的回答,这不仅是单一性,还与违约类型有关。 a
和b
可以单式为Double
,如在GHC编译的函数中那样,但是由于单态限制和逐行类型推断的组合,我们无法获得x :: Num a => a
或x :: Double
- 两者都适合您需要。
这是monomorphism restriction在工作。 a
和b
的类型默认为Integer
,显然不能与/
一起使用,因为它只适用于Fractional
类型。
您可以通过添加类型注释定义a
和b
时解决这一问题:
> let a = 5 :: Double
> let b = 2 :: Double
> a/b
2.5
,或者您可以使用十进制文本将默认为Double
:
> let a = 5.0
> let b = 2.0
> a/b
2.5
这不会是一个问题如果这三行是类型检查在一起,因为他们将在编译模块,或者如果您已输入
let a = 5; b = 2 in a/b
然而,当在GHCI单独类型的,它们是类型检查一次一个,所以违约,在评价let a = 5
拾取Integer
当施加因为在那个点上的a
唯一的限制是Num
。它不知道我们需要的Fractional
约束,以便稍后使用/
。
正如其他人所指出的,这是Monomorphism Restriction的错。相反注释所有的类型,如(a :: Double)/(b :: Double)
的,我觉得很容易,只需将其关闭:
Prelude> :set -XNoMonomorphismRestriction
Prelude> let a = 5
Prelude> let b = 2
Prelude> a/b
2.5
(您可以保存:set
行动在.ghci file,所以你不需要每次写)
你从哪里找到'-XNoMonomorphismRestriction',我在哪里可以找到更多像这样的东西,还有其他问题? – CodyBugstein 2013-04-28 20:44:03
@Imray:GHC用户指南很长很密集,但充满了这样的有用工具。尝试http://www.haskell.org/ghc/docs/latest/html/users_guide/ghc-language-features.html。 Haskell wiki也有很多很棒的信息,但它更加分散。 – amindfv 2013-04-29 05:16:09