2016-09-22 99 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

增加了一些解释 –