2015-10-15 57 views
1

我是Haskell世界的新手,所以这可能是一个基本问题。Haskell - 在构造函数中推断类型

难道这代码:

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

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)) 

在没有明确的类型的表达?

该表达式:

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

其是较短的是不模糊的,如(整数15)不适合(根结线虫字串)的定义,但它不编译:

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))' 

为什么?

回答

5

在表达

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

Numero不是一个类型 - 但 值构造,所以你需要它,以构建 东西 Elemento类型的值。

一种方法是使用fromIntegral以实现“自动”转换。

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

在一个侧面说明:我觉得它使你的代码更加混乱,你有一个类型的NumeroNumero一个类型构造,其中后者是构建东西Elemento类型。

我会用NumElementoVarElemento或类似的东西。


更简洁,但完全不同的方法(如写在我的意见),是使用多项式来代替monomes。

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

这种方法解决出现的许多问题,如果你很小心,你甚至可以代表泰勒(拯救你不检查羯羊您选择不检查cosine == cosine - 虽然显然是正确的,但你碰巧在无限的比较过程中运行)。

+0

我可以看到'instance Num Numero where fromInteger = Integer; [...]',但你会如何为Elemento创建一个实例? – Bergi

+0

*我会使用NumElemento和VarElemento或类似的东西。*你的意思是将'Incognita String'连接到** Numero **构造函数吗? – lilezek

+0

我的意思是我会使用'NumElemento'来表示我为'变量'构造了'Elemento','VarElemento'类型的东西 - 你称之为'Incognita'。 – epsilonhalbe

相关问题