[英]using custom data types in haskell
I made these custom data types:我制作了这些自定义数据类型:
data BakedGoods = Muffin
| Croissant
| Cookie
deriving (Eq, Show)
data Muffin = Blueberry
| SaltedCaramel
| Cheesecake
then I tried to use them in a function that returns the price of the BakedGoods:然后我尝试在返回 BakedGoods 价格的函数中使用它们:
price :: BakedGoods -> Int
price a
| a == Blueberry = 2
[...]
and I keep getting this error:我不断收到此错误:
Couldn't match expected type ‘BakedGoods’ with actual type ‘Muffin’
I get the point but unfortunately I have no idea how to fix it, do you have any ideas?我明白了,但不幸的是我不知道如何解决它,你有什么想法吗? :)
:)
This is a bit confusing for beginners.这对初学者来说有点混乱。
An algebraic datatype is of the form: data
typename =
constructor1 |
代数数据类型的形式如下:
data
typename =
constructor1 |
constructor2 etc.构造函数2等
A type can have the same name as a constructor, even of a different type.类型可以与构造函数同名,即使是不同的类型。 So your code has two different
Muffin
s - a type called Muffin
(with constructors Blueberry
, SaltedCaramel
and Cheescake
), and a constructor Muffin
for the type BakedGoods
.所以你的代码有两个不同的
Muffin
s - 一个叫做Muffin
的类型(带有构造函数Blueberry
, SaltedCaramel
和Cheescake
),以及一个用于类型BakedGoods
的构造函数Muffin
。 As far as the compiler is concerned, they are completely unconnected.就编译器而言,它们是完全没有联系的。
The code you want looks like this:您想要的代码如下所示:
data BakedGoods = Muffin Muffin
| ...
This means: The type BakedGoods
has a constructor called Muffin
, which contains one field of type Muffin
.这意味着:
BakedGoods
类型有一个名为Muffin
的构造函数,其中包含一个Muffin
类型的字段。
You would then pattern-match it like so:然后你可以像这样模式匹配它:
price :: BakedGoods -> Int
price (Muffin Blueberry) = 2
...
Which means: when the argument (which must be a BakedGoods
) has a top-level constructor matching Muffin
, whose field (of type Muffin
) matches Blueberry
, then return 2.这意味着:当参数(必须是
BakedGoods
)具有匹配Muffin
的顶级构造函数,其字段(类型Muffin
)匹配Blueberry
,则返回 2。
Happy Haskelling!哈斯克林快乐!
If you write如果你写
data BakedGoods = Muffin | …
then this is not a union of the data constructors of the Muffin
type with other data constructors.
Muffin
类型的数据构造函数与其他数据构造函数的联合。
You here simply say that BakedGood
s has a data constructor named Muffin
, the fact that there is a type named Muffin
does not matter.
BakedGood
s 有一个名为Muffin
的数据构造函数,事实上有一个名为Muffin
的类型并不重要。
You can wrap a Muffin
object in the Muffin
data constructor, like:您可以在
Muffin
数据构造函数中包装一个Muffin
对象,例如:
data BakedGoods
= Muffin
Muffin -- ← parameter for the Muffin data type
| Croissant
| Cookie
deriving (Eq, Show)
Then you thus can perform pattern matching on the value wrapped in the Muffin
data constructor:然后,您可以对包裹在
Muffin
数据构造函数中的值执行模式匹配:
price :: BakedGoods -> Int
price (
Muffin Blueberry) = 2
When you do当你做
data BakedGoods = Muffin -- ...
data Muffin = Blueberry -- ...
You are not saying that BakedGoods
's data constructors should include all of Muffin
's.您并不是说
BakedGoods
的数据构造函数应该包括所有Muffin
的数据构造函数。 You are actually saying that you should create a new Muffin
data constructor, completely unrelated to the Muffin
type, and that Muffin
data constructor is a BakedGood
.您实际上是说您应该创建一个新的
Muffin
数据构造函数,与Muffin
类型完全无关,并且Muffin
数据构造函数是BakedGood
。 If you want to merge the two, then declare them merged:如果要合并两者,则声明它们合并:
data BakedGoods = Blueberry
| SaltedCaramel
| Cheesecake
| Croissant
| Cookie
Then Blueberry
would be a BakedGoods
.那么
Blueberry
将成为BakedGoods
。 But, if you want to retain the fact that they are muffins, then you can make a MuffinFlavor
type and have your Muffin
contain a MuffinFlavor
:但是,如果你想保留它们是松饼的事实,那么你可以制作一个
MuffinFlavor
类型并让你的Muffin
包含一个MuffinFlavor
:
data BakedGoods = Muffin MuffinFlavor
| Croissant
| Cookie
data MuffinFlavor = Blueberry | SaltedCaramel | Cheesecake
And now you can create muffins with Muffin Blueberry
.现在您可以使用
Muffin Blueberry
制作松饼。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.