内哈斯克尔返回特定类型(Return specific type within Haskell)

2019-07-21 08:04发布

我对Haskell的类型系统一个相当普遍的问题。 我试图去熟悉它,我有以下功能:

getN :: Num a => a
getN = 5.0 :: Double

当我尝试编译,我得到以下错误:

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

据我了解这一点,功能是建立在阶级民“回归”一类。 双是在这个类( http://www.zvon.org/other/haskell/Outputprelude/Num_c.html ),所以我本来期望它会好起来的“重返”双精度在这种情况下。

有人能解释这个吗?

Answer 1:

与签名函数Num a => a预期用于任何类型在类工作Num 。 实现5.0 :: Double只适用于一个类型,而不是对所有类型之类的,所以编译器会抱怨。

泛型函数的一个例子是:

square :: (Num a) => a -> a
square x = x * x

这适用于任何类型的是Num 。 它适用于您要使用双打,整数和任何其他数字。 正因为如此它可以有,只是需要的参数是在课堂上泛型类型签名Num 。 (Type类Num是必要的,因为该函数使用乘法* ,其定义有)



Answer 2:

为了增加某事的回答是:Haskell是不是面向对象的。 这是不正确的Double是的一个子类Num ,所以你不能返回Double如果你答应返回一个多态Num值一样可以,比方说,Java的。

当你写getN :: Num a => a你答应返回的值是完全内多态性Num约束。 实际上,这意味着你只能使用从功能上Num型类,如+*-fromInteger



Answer 3:

检查出存在性量化类型

解决这个问题的一种方法是定义一个新的数据类型

data NumBox = forall n. Num n => NumBox n

你需要-XExistentialQuantification得到这个工作。

现在,你可以写类似

getN :: NumBox
getN = NumBox (5.0 :: Double)

您还可以定义一个NumBox -list为

let n3 = [NumBox (4.0 :: Double), NumBox (1 :: Integer), NumBox (1 :: Int) ]


文章来源: Return specific type within Haskell