2015-10-15 53 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

相關問題