如果你需要一個背景下,最簡單的辦法是給我們E中的data
聲明:
data (Integral a) => IntegralData a = ID [a]
type ListOfIntegralData a = [IntegralData a]
*Main> :t [ ID [1234,1234]]
[ID [1234,1234]] :: Integral a => [IntegralData a]
這具有確保一個Integral
上下文被添加到使用IntegralData
數據類型每一個功能的(唯一)的效果。
sumID :: Integral a => IntegralData a -> a
sumID (ID xs) = sum xs
主要的原因type
同義詞不適合你的工作是類型同義詞被設計成 只是 - 這取代了型,不是類型簽名。
但是,如果你想要去生存的最好方式是用GADT,因爲它處理爲您的所有量化的問題:
{-# LANGUAGE GADTs #-}
data IntegralGADT where
IG :: Integral a => [a] -> IntegralGADT
type ListOfIG = [ IntegralGADT ]
因爲這基本上是一個存在的類型,你可以將它們混合起來:
*Main> :t [IG [1,1,1::Int], IG [234,234::Integer]]
[IG [1,1,1::Int],IG [234,234::Integer]] :: [ IntegralGADT ]
根據您的應用,您可能會發現它非常方便。
一個GADT在數據聲明的主要優點是,當你的模式匹配,您隱得到Integral
背景:
showPointZero :: IntegralGADT -> String
showPointZero (IG xs) = show $ (map fromIntegral xs :: [Double])
*Main> showPointZero (IG [1,2,3])
"[1.0,2.0,3.0]"
但存在量化有時用於錯誤的原因, (如希望將所有數據混合在一個列表中,因爲這就是您從動態類型語言中習得的 ,而且您還沒有習慣於使用靜態類型及其優點(例如 ))。
這裏我認爲它比它的價值更麻煩,除非你需要需要將不同的 積分類型組合在一起而不轉換它們。我看不到原因 爲什麼這會有所幫助,因爲您在使用它們時必須將其轉換。
例如,你不能定義
unIG (IG xs) = xs
,因爲它甚至不鍵入檢查。經驗法則:你不能在右邊提到類型a
。
然而,這是可以的,因爲我們轉換類型a
:
unIG :: Num b => IntegralGADT -> [b]
unIG (IG xs) = map fromIntegral xs
這裏存在量化迫使您將您的數據時,我認爲你原來的計劃是不就得了! 你也可以把所有東西都轉換成Integer而不是這個。
如果你想簡單的事情,讓他們簡單。數據聲明是確保您不會將數據放入數據類型的最簡單方法,除非它已經是某個類型類的成員。
'ListOfAsdf2'也需要一個類型參數。 '輸入ListOfAsdf2 a =整數a => [Asdf2 a]'。 –
我也試過,但是我得到了同樣的錯誤.. =( – dak
是的,你需要'ImpredicativeTypes',就像編譯器說的那樣。但實際上,你不需要type參數 –