简体   繁体   English

Haskell-合并数据类型?

[英]Haskell - Combining datatypes?

I'm new to Haskell, I've looked around for an answer to the below but had no luck. 我是Haskell的新手,我一直在寻找以下内容的答案,但没有运气。

Why doesn't this code compile? 为什么此代码无法编译?

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))

Error: 错误:

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

However, this compiles just fine: 但是,这样编译就可以了:

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

I realize there's simpler ways of doing the above, but I'm just testing the different uses of custom data types. 我意识到可以采用更简单的方法来进行上述操作,但是我只是在测试自定义数据类型的不同用法。

Update: 更新:

My inclination is that the compiler doesn't like 'exampleFunction ::Characteristics abc' because its not type safe. 我的倾向是编译器不喜欢'exampleFunction :: Characteristics abc',因为它的类型不安全。 ie I'm providing no guarantee of: a == Name String, b == Age Int, c == Height Int. 即我不提供以下保证:a ==名称字符串,b ==年龄整数,c ==高度整数。

exampleFunction is too general. exampleFunction太笼统了。 You are claiming it can take a Characteristics abc value for any types a , b , and c . 您声称它可以为abc 任何类型a Characteristics abc值。 However, the value of type a is passed to Name , which can only take a value of type String . 但是,类型a的值传递给Name ,后者只能采用String类型的值。 The solution is to be specific about what types the characteristics can actually be. 解决方案是具体说明特征实际上可以是什么类型。

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

Consider, though, that you may not even need newtype s here; 但是,请考虑一下,在这里甚至可能不需要newtype simple type aliases may suffice. 简单类型别名就足够了。

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

Try this: 尝试这个:

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

The reason this works, and yours does not, is that Name, Age and Height require specific types where your example function took completely generic arguments. 之所以起作用,而您却不起作用,是因为Name,Age和Height需要特定类型,您的示例函数使用了完全通用的参数。

The a,b and c in this line of your example defines the type of the arguments, not the name of them. 示例行中的a,b和c定义了参数的类型,而不是参数的名称。

 exampleFunction :: Characteristics a b c 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM