2016-09-22 97 views
1

我是Haskell的新手,我已經四處尋找答案,但沒有運氣。Haskell - 組合數據類型?

這段代碼爲什麼不編譯?

newtype Name = Name String deriving (Show, Read) 
newtype Age = Age Int deriving (Show, Read) 
newtype Height = Height Int deriving (Show, Read) 

data User = Person Name Age Height deriving (Show, Read) 

data Characteristics a b c = Characteristics a b c 

exampleFunction :: Characteristics a b c -> User 
exampleFunction (Characteristics a b c) = (Person (Name a) (Age b) (Height c)) 

錯誤:

"Couldn't match expected type ‘String’ with actual type ‘a’,‘a’ is a rigid type, variable bound by the type signature" 

然而,這個編譯就好:

exampleFunction :: String -> Int -> Int -> User 
exampleFunction a b c = (Person (Name a) (Age b) (Height c)) 

我意識到人們做上述的簡單的方法,但我只是測試的不同用途自定義數據類型。

更新:

我的傾向是,編譯器不喜歡 'exampleFunction ::特性A B C',因爲它不是類型安全的。即我不提供以下保證:a ==姓名字符串,b == Age Age,c ==高度Int。

回答

6

exampleFunction過於籠統。您聲稱可能需要Characteristics a b c任意類型a,bc。但是,類型a的值傳遞給Name,其中只有取值爲String。解決方案是具體說明哪些類型的特徵可以實際存在。

exampleFunction :: Characteristics String Int Int -> User 
exampleFunction (Characteristics a b c) = (Person (Name a) (Age b) (Height c)) 

想想,雖然你可能甚至不需要newtype s在這裏;簡單類型的別名就足夠了。

type Name = String 
type Age = Int 
type Height = Int 

type Characteristics = (,,) 

exampleFunction :: Characteristics Name Age Height -> User 
exampleFunction (Charatersics n a h) = Person n a h 
+0

謝謝,我剛剛更新了我的問題,同時有相當多這樣:P –

2

試試這個:

exampleFunction :: Characteristics String Int Int -> User 
exampleFunction (Characteristics a b c) = (Person (Name a) (Age b) (Height c)) 

這部作品的原因,你沒有,是姓名,年齡和身高需要特定類型的在您的例子功能完全接管通用的參數。

您示例的這一行中的a,b和c定義了參數的類型,而不是它們的名稱。

exampleFunction :: Characteristics a b c 
+0

這不解釋錯誤,只是摑下來編譯:-) – jarandaf

+0

增加了一些解釋 –