2014-10-31 74 views
3

如何理解Haskell的“1.2%3.4”的错误消息?如何理解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> 
+0

也许你应该直接设置表达式的类型? (4.3%1.2)::漂浮或水手。也许haskell无法为此表达式导出类型 – 2014-10-31 07:26:45

+1

ghc给出的所有错误消息中,这是最糟糕的之一。它不会告诉你实际的问题。你的表达式的类型是'(积分a,分数a)=>比率a'。但是,没有一种既是“积分”也是“分数”的类型。默认失败(它应该真的告诉你),它会为表达式'print(4.3%1.2)'发出一个错误,而不是你实际输入的内容。你的问题是“比率”是两个*整数*的比率,所以'4.3%1.2'没有任何意义。 '4%3'或类似的工作正常。 – user2407038 2014-10-31 07:29:34

回答

5

这种类型的错误信息是有点不友好,我认为。

什么是真正发生在这里是你的表达具有类型

Prelude Data.Ratio> :t 4.3 % 1.2 
4.3 % 1.2 :: (Integral a, Fractional a) => Ratio a 

Integral a意味着你的类型a必须是整数样,而Fractional a意味着它必须浮点或理性等。标准Haskell中没有哪种类型都是。

当为了打印评估这个表达式,GHCI第一推断它的类型,与额外的限制,它需要打印:

(Integral a, Fractional a, Show a) => Ratio a 

现在,因为这仍然过于模糊评价,GHCI试图拖欠aIntegerDouble。但是它们都不适合这里,每个类都只是IntegralFractional中的一个类的成员。

然后,在违约失败后,GHCi会给出一条错误消息,告诉您一个一个它未能满足的约束条件。特别是容易混淆的,它正好选择哪个无关与失败的原因之一......

总之,要解决你的问题:%功能分隔两个有理数,它是功能从整数类分子和分母构造一个理性。为了鸿沟他们,而不是使用

4.3/1.2 :: Rational 

:: Rational告诉你想要一个合理的(而不是默认的Double否则它将选择),以及浮点记号确实工作做出GHCI一个Rational - 它是类型类别Fractional提供的功能之一。