为什么"(1 + 1.0)"的类型为"Fractional a => a"而不是"Num a => a"?

sta*_*ser 1 haskell

1 有类型 Num a => a

1.0 有类型 Fractional a => a

为什么1+1.0有类型Fractional a => a

这对我来说似乎很奇怪,因为1它不是分数.只是1.0分数.那么怎么1变成分数并结合1.0形成一个小数?

因为只有Num拥有+运营商,如果它似乎更自然的我1.0变成了Num,得到了与组合1以产生最终的Num(虽然这将是奇怪的一点,因为我们会失去信息,从去1.01).

sep*_*p2k 9

每个分数都是一个Num,但不是每个Num都是一个Fractional.因此,如果我们有一个Num喜欢1,它可能是Fractional(因为有些Nums是Fractionals)或者它不可能.但是1.0只能是一个Fractional,它绝对不能Num像其他一样Integer.

因此,当编译器看到你向a添加1时Fractional,它意识到在这种情况下1必须是一个Fractional- 否则你不允许将它添加到a Fractional.


这是一个类似示例的示例,它只涉及用户定义的类型类而不是Nums.也许这会让事情更加清晰:

class Foo a where
  foo :: a

class Foo a => Bar a where
  bar :: a
  combine :: a -> a -> a
Run Code Online (Sandbox Code Playgroud)

通过上面的类型类,我们现在有以下方法:

foo :: Foo a => a
bar :: Bar a => a
combine :: Bar a => a -> a -> a
Run Code Online (Sandbox Code Playgroud)

所以现在让我们尝试结合foobar喜欢这样:

combine foo bar
Run Code Online (Sandbox Code Playgroud)

这大致相当于您尝试在示例中添加1(类型Num a => a)和1.0(类型Fractional a => a).就像你的例子一样,这个工作正常并且有类型Bar a => a.