Haskell 了解a/b为什么不';不起作用,但fromInteger a/fromInteger b起作用
在Haskell中,这是有效的:Haskell 了解a/b为什么不';不起作用,但fromInteger a/fromInteger b起作用,haskell,Haskell,在Haskell中,这是有效的: 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 fo
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>
fromInteger怎么了?为什么我需要它来完成这项工作?这是工作中的关键。a
和b
的类型默认为Integer
,这显然不能与/
一起使用,因为它只适用于分数类型
您可以通过在定义a
和b
时添加类型注释来解决此问题:
> let a = 5 :: Double
> let b = 2 :: Double
> a / b
2.5
或者您可以使用默认为双精度的十进制文字:
> 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
。它不知道我们以后使用/
时需要的分数约束
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 type将let绑定变量默认为整数
,它没有分数
实例(因为整数
不是分数)。在通过ghc编译的Haskell程序中,类型将统一
编辑:我应该补充一点,我试图指出,如果在更大的上下文中,而不是在GHCi中,如何将let x=4
推断为Double。作为对Hammar答案的回应,这不仅仅是单态,还与类型缺省有关a
和b
可以是单形态的双
,如在GHC编译函数中,但是,由于单态限制和逐行类型推断的组合,我们无法得到x::Num a=>a
或x::Double
——这两者都适合您的需要。正如其他人所指出的,这是。与注释所有类型(如(a::Double)/(b::Double)
)不同,我发现关闭它更容易:
Prelude> :set -XNoMonomorphismRestriction
Prelude> let a = 5
Prelude> let b = 2
Prelude> a / b
2.5
(您可以在中保存:设置操作,这样您就不必每次都编写它了)您在哪里找到了-XNoMonomorphismRestriction
,对于我的其他问题,我在哪里可以找到更多类似它的内容?@Imray:GHC用户指南既长又密集,但充满了这样的有用工具。尝试Haskell维基也有很多很好的信息,但它更分散。
Prelude> :set -XNoMonomorphismRestriction
Prelude> let a = 5
Prelude> let b = 2
Prelude> a / b
2.5