Haskell - 在构造函数中推断类型

时间:2015-10-15 22:52:02

标签: haskell type-inference

我是Haskell世界的新手,所以这可能是一个基本问题。

这段代码可以:

data Numero =
  Integer Integer |
  Rational Rational |
  Double Double
  deriving (Show)
data Elemento =
  Numero Numero |
  Incognita String
  deriving (Show)

data Monomio = Monomio {base :: Elemento, exp :: Numero} deriving(Show)

main = print (Monomio (Numero (Integer 15)) (Integer 20))

在没有明确类型的情况下表达:

(Monomio (Numero (Integer 15)) (Integer 20))

这个表达式:

main = print (Monomio (Integer 15) (Integer 20))

更短是不明确的,因为(整数15)不符合(Incognita字符串)的定义,但它没有编译:

main.hs:13:24:
    Couldn't match expected type `Elemento' with actual type `Numero'
    In the first argument of `Monomio', namely `(Integer 15)'
    In the first argument of `print', namely
      `(Monomio (Integer 15) (Integer 20))'

为什么?

1 个答案:

答案 0 :(得分:5)

表达式中的Numero

(Monomio (Numero (Integer 15)) (Integer 20))

不是类型 - 而是类型值构造函数,因此您需要它来构造某事类型为Elemento的值。

一种方法是使用fromIntegral来实现"自动"转换。

对于String - 就像你有OverloadedStrings - 语言扩展,但对于数字类型,没有类似的东西(至少据我所知)。

旁注:我认为这会使您的代码更加混乱,因为您有Numero类型和Numero类型构造函数,后者构造类型为{{1}的类型}}

我会使用ElementoNumElemento之类的东西。

更简洁但完全不同的方法(如我的评论中所述),将使用多项式而不是单体。

VarElemento

此处data Polynomial1 = P1 String [Rational] newtype Polynomial = P [Polynomial1] 代表P1 "X" [1,2,3]p(x) = 1 + 2*x + 3*x²代表P [P1 "X" [1,2], P1 "Y" [0,1]]

这种方法解决了许多出现的问题,如果你小心你甚至可以代表泰勒系列(保存你不会检查你是不是在检查p(x,y) = 1 + 2*x + y - 尽管显然是真的,你碰巧在一个无限的比较过程)。