在 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 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 将 let 绑定(bind)的变量默认为 Integer ,它没有 Fractional 实例(因为 Integer 不是分数)。在通过 ghc 编译的 Haskell 程序中,类型将统一。

编辑:我应该补充一点,我想说明如何将 let x = 4 推断为 Double 在更大的上下文中,而不是在 GHCi 上。作为对 Hammar 的回答的回应,它不仅仅是单态,还与类型默认有关。 ab 可以是 Double ,就像在 GHC 编译的函数中一样,但是由于单态限制和逐行类型推断的组合,我们无法获得 x :: Num a => ax :: Double - 这两者都适合您需要。

关于haskell - 理解为什么 a/b 不起作用,但 fromInteger a/fromInteger b 起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16244612/

10-12 03:46