2011-09-02 152 views
4

我有一個類型定義構造函數NEWTYPE

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] 

我環顧四周,換一種方式來指定NEWTYPE的構造。我意識到只能有一個,但我不明白爲什麼我可以指定它是什麼。

例如,我可能只想將參數的前三個元素帶到PolyRing值構造函數中。

我試着在newtype聲明的結尾處使用where子句添加,但沒有編譯。

我也嘗試:

(PolyRing xs) = PolyRing [2, 3, 5, 7] 

作爲玩具的例子。我認爲這應該做的是忽略值構造函數的參數,並始終具有值[2,3,5,7]。代碼編譯,但我的「自定義」構造函數沒有效果。

是否可以指定新類型的構造函數?

+0

我不明白這個問題。當你執行'newtype PolyRing a n = PolyRing [a]'時,你指定了構造函數。如果你想調用構造函數,可以使用'newtype PolyRing a n = SomethingElse [a]'。 – sepp2k

+0

我不想重命名它,我想在施工過程中做某些事情。確切地說, – crockeea

回答

7

我認爲你要找的是Smart constructor

PolyRing的基本大寫的構造函數不能被重載。但你可以做到這一點:

polyRing :: (Num a, IntegerAsType n) => [a] -> PolyRing a n 
polyRing = PolyRing . take 3 

,或者甚至更好:

polyRing :: (Num a, IntegerAsType n) => [a] -> Maybe (PolyRing a n) 
polyRing (a:b:c:_) = Just $ PolyRing [a, b, c] 
polyRing _   = Nothing 

爲了防止有人直接使用PolyRing構造,在該文件可能看起來像的頂端的模塊出口報關這個:

module PolyRing (
PolyRing(), -- Export the PolyRing type but not constructor 
polyRing  -- Your smart constructor 
) where 

在OO中,封裝單元是類,但在Haskell中,它是模塊。

+0

。謝謝! – crockeea