2012-07-19 97 views
3

我是Haskell的新手,並試圖用實例創建一個類。Haskell無法創建TypeClass的實例

我有下面的代碼,我想說的是: 1)科能在其第一位置保存任何類型, 2)使類線性這需要線性的東西,並返回一個數 3)製作如果分支持有的第一件東西是Num類的一部分,則分支Linear的一個實例。

data Branch a = Branch a Integer deriving (Show, Eq) 

class Linear l where 
    length :: (Num a) => l -> a 

instance (Num a) => Linear (Branch a) where 
    length (Branch len _) = len 

我得到的錯誤: 無法推斷(一〜A1) 從由實例聲明的約束範圍內(民一).....

有誰知道如何表達在Haskell中,我想說什麼?

回答

8

你的類定義說length必須能夠返回用戶請求的任何Num類型。所以如果用戶想要一個整數,長度方法必須給他一個整數。如果他想要一個Int或Double,長度也必須給他。

但是,您在實例聲明中提供的長度函數不符合要求。例如,當您撥打Branch Integer的長度時,長度將返回Integer。即使用戶要求,它也不會返回IntDouble

使代碼工作的一種方法是使用多參數類型類來定義具有兩個參數的Linear,其中第二個類型是數字類型length應該返回。然後你可以有一個Linear (Branch a) a的實例。您可能還想使用功能依賴關係擴展來使其更加可用。而不是第二個類型參數,您也可以使用類型系列擴展來實現類似的效果。

另一種方法是將實例聲明更改爲需要Integral a而不是Num a,然後使用fromIntegral len作爲返回值。這會將存儲在分支中的整數類型轉換爲用戶請求的任何數字類型。當然,警告是你用非整數數值分支,這樣不會是Linear的實例。

+0

我試圖理解多參數類型類,但它們超出了我的級別。 – WuHoUnited 2012-07-21 00:33:10