在Haskell中返回特定类型

Lit*_*rum 14 haskell types type-systems compiler-errors typeclass

关于Haskell的类型系统,我有一个相当普遍的问题.我正在努力熟悉它,我有以下功能:

getN :: Num a => a
getN = 5.0 :: Double
Run Code Online (Sandbox Code Playgroud)

当我尝试编译它时,我收到以下错误:

Couldn't match expected type `a' against inferred type `Double'
  `a' is a rigid type variable bound by
      the type signature for `getN' at Perlin.hs:15:12
In the expression: 5.0 :: Double
In the definition of `getN': getN = 5.0 :: Double
Run Code Online (Sandbox Code Playgroud)

据我了解,该函数设置为"返回"类Num中的类型.Double是在这个类中(http://www.zvon.org/other/haskell/Outputprelude/Num_c.html),所以我原本预计在这种情况下"返回"Double是可以的.

有人可以解释一下吗?

sth*_*sth 15

具有签名的函数Num a => a应该适用于类中的任何类型Num.该实现5.0 :: Double只适用于一种类型,而不适用于所有类型的类,因此编译器会抱怨.

泛型函数的一个示例是:

square :: (Num a) => a -> a
square x = x * x
Run Code Online (Sandbox Code Playgroud)

这适用于任何类型的Num.它适用于双打,整数和您想要使用的任何其他数字.因此,它可以具有通用类型签名,只需要参数在类中Num.(类型类Num是必需的,因为函数使用乘法*,在那里定义)


Mar*_*ijn 8

添加到某人的答案:Haskell不是面向对象的.它不是真正Double的子类Num,所以Double如果你保证返回一个多态Num值,你就不能返回一个,就像你可以在Java中那样.

当你写的时候,getN :: Num a => a你承诺在Num约束内返回一个完全多态的值.实际上,这意味着你只能使用从功能Num型类,如+,*,-fromInteger.