Haskell - 结合数据类型?

时间:2016-09-22 14:42:10

标签: haskell types

我是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 :: Characteristics a b c',因为它不是类型安全的。即我不保证:a == Name String,b == Age Int,c == Height Int。

2 个答案:

答案 0 :(得分:6)

exampleFunction过于笼统。您声称​​任何类型Characteristics a b cab可能需要c值。但是,a类型的值会传递给Name,而的值为String。解决方案是具体说明特征的实际类型。

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

但请考虑一下,你甚至可能不需要newtype;简单类型别名就足够了。

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

答案 1 :(得分:2)

试试这个:

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

这是有效的,而你的不是,Name,Age和Height需要特定的类型,你的示例函数采用完全通用的参数。

示例的这一行中的a,b和c定义了参数的类型,而不是它们的名称。

 exampleFunction :: Characteristics a b c