Haskell - 结合数据类型?

Bab*_*ham 1 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))
Run Code Online (Sandbox Code Playgroud)

错误:

"Couldn't match expected type ‘String’ with actual type ‘a’,‘a’ is a rigid type, variable bound by the type signature"
Run Code Online (Sandbox Code Playgroud)

但是,编译得很好:

exampleFunction :: String -> Int -> Int -> User
exampleFunction a b c = (Person (Name a) (Age b) (Height c))
Run Code Online (Sandbox Code Playgroud)

我意识到有更简单的方法来做上述事情,但我只是测试自定义数据类型的不同用途.

更新:

我倾向于编译器不喜欢'exampleFunction :: Characteristics abc',因为它不是类型安全的.即我不保证:a == Name String,b == Age Int,c == Height Int.

che*_*ner 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))
Run Code Online (Sandbox Code Playgroud)

但是请考虑一下,你甚至可能不需要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
Run Code Online (Sandbox Code Playgroud)