如何理解Haskell的"1.2%3.4"的错误消息?

qaz*_*wsx 3 haskell typeclass

如何理解Haskell的"1.2%3.4"的错误消息?

Prelude> :m +Data.Ratio
Prelude Data.Ratio> 4.3 % 1.2

<interactive>:11:1:
    No instance for (Show a0) arising from a use of ‘print’
    The type variable ‘a0’ is ambiguous
    Note: there are several potential instances:
      instance Show Double -- Defined in ‘GHC.Float’
      instance Show Float -- Defined in ‘GHC.Float’
      instance (Integral a, Show a) => Show (Ratio a)
        -- Defined in ‘GHC.Real’
      ...plus 23 others
    In a stmt of an interactive GHCi command: print it
Prelude Data.Ratio> 
Run Code Online (Sandbox Code Playgroud)

Ørj*_*sen 5

我想,这种类型的错误信息有点不友好.

这里实际发生的是你的表达式有类型

Prelude Data.Ratio> :t 4.3 % 1.2
4.3 % 1.2 :: (Integral a, Fractional a) => Ratio a
Run Code Online (Sandbox Code Playgroud)

Integral a意味着你的类型a必须是整数类,同时Fractional a意味着它必须是浮点或类似理论.标准Haskell中没有类型都是.

在评估此表达式以进行打印时,GHCi首先推断其类型,以及需要打印的附加限制:

(Integral a, Fractional a, Show a) => Ratio a
Run Code Online (Sandbox Code Playgroud)

现在因为这仍然太模糊不清楚,GHCi试图默认 aInteger或者Double.但他们都不适合这里,是每个班级只有一个成员IntegralFractional.

然后,在默认失败后,GHCi会给出一条错误消息,告诉您它无法满足的约束条件之一.特别令人困惑的是,碰巧选择与失败原因无关的那个......

总之,要解决你的问题:%不是分隔两个有理数的功能,它是构建一个理性的从类似于整数分子和分母的功能.要改为划分它们,请使用

4.3 / 1.2 :: Rational
Run Code Online (Sandbox Code Playgroud)

:: Rational告诉你想要一个合理的(而不是默认的GHCI Double否则它将选择),以及浮点表示法工作,使一个Rational-它的特点之一Fractional类型类提供.