2011-09-02 27 views
3

我有一個類型強制轉換到多參數類型在Haskell

class IntegerAsType a where 
    value :: a -> Integer 

data T5 
instance IntegerAsType T5 where value _ = 5 

newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a] 

我的主要問題是:我怎麼定義一個特定PolyRing變量?

它應該是這樣的:

x = [1, 2, 3] :: Integer T5 

(我認爲) 的問題是:什麼是::後的正確語法?

,我發現了錯誤

Couldn't match expected type `PolyRing Integer T5' 
     with actual type `[t0]' 
In the expression: [1, 2, 3] :: PolyRing Integer T5 
In an equation for `x': x = [1, 2, 3] :: PolyRing Integer T5 

另外,我正在尋找一種更好的方式來實現這一點。特別是,我真的很喜歡類型a從列表元素的類型推斷,而IntegerAsType n必須指定(它應該不取決於列表的長度,即使這是可能的)。

事情我試過到目前爲止:

x = [1,2,3] :: PolyRing (Integer, T5) 

x = [1,2,3] :: PolyRing Integer T5 

回答

2

首先注意

數據類型的上下文,如:

newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a] 

一般都是餿主意,從語言已經退休了。

忽略

構建您必須使用數據構建器PolyRing一個實例:

PolyRing [1,2,3] 

但是,這是不夠的,類型推斷至今將(IntegerAsType n) => PolyRing Integer n。您的最終類型簽名將完成此let x = PolyRing [1,2,3] :: PolyRing Integer T5

返回到第一注

不過,也許你想要的東西:

newtype PolyRing a n = PolyRing [a] 

而且每一個構建或消耗polyring可以實施必要的限制功能:

func :: (Num a, IntegerAsType n) => PolyRing a n -> ... 
2

一個newtype不只是一個代名詞,但一個方法來創建一個類型,它是在類型級別不同(雖然相同更高版本)。這就是說 - 你需要使用你的數據構造函數明確地包裝它。此外,上下文不起作用。你仍然需要在任何地方輸入。