如何定义由其他数据类型组成的数据类型?

How do I define a data type consisting of other data types?

我想定义货币数据类型,它由其他三种数据类型组成。我遇到的问题是 Haskell 无法将数据类型识别为货币的一部分,这会破坏一切。

我的想法是将不同的货币定义为它们自己的数据类型,然后将它们添加到我尝试过的货币类型中:

data Euro = MkEuro Integer Integer
data Dollar = MkDollar Integer Integer
data Yen = MkYen Integer
data Currency = Euro | Dollar | Yen

如果我想在任何函数中使用货币类型,我会收到以下错误消息的变体:

Couldn't match expected type `Currency' with actual type `Dollar'

遗憾的是,我必须使用货币类型,无法为所有三种货币创建不同的函数。

目前您的 Currency 被构造为三个值,它们采用 参数。所以Euro是一个值,Dollar是一个值,Yen是一个值,但不是MkYen 15.

您可以向数据构造函数添加参数,例如:

data Currency = Euro <b>Euro</b> | Dollar <b>Dollar</b> | Yen <b>Yen</b>

然后你可以构造一个 Currency 有:

<b>Euro</b> (MkEuro 14 25) :: Currency

:: Currency 不需要MkEuro会构造一个Euro类型的对象,然后我们使用Eurodata构造函数Euro -> Currency来构造一个Currency.

Sadly I have to use the type Currency and can't create different functions for all three currencies.

你可能想制作一个 Currency typeclass 但是,它提供了一个接口来说明货币应该实现什么功能,然后制作 EuroDollarYen 个该类型类的实例。

您尝试的问题是前 3 行([=14 的左侧)定义的 EuroDollarYen =] 符号)是 类型 ,而最后一行右侧的那些是 数据构造函数 。这些是不同的东西,这就是为什么你可以给它们相同的名字 - 但也意味着 value Dollartype Currency, 不是类型 Dollar.

您创建一个结合其他三个的联合类型的想法是正确的 - 但您将数据构造函数(只是 "tags")与它们所持有的值的类型混淆了。您可以这样修复它:

data Currency = Euro Euro | Dollar Dollar | Yen Yen

两次(也是三次)使用相同的名称可能看起来令人困惑 - 但两次出现的名称具有不同的含义。比如在Euro Euro中,第一个Euro是一个数据构造器(一个函数里面"tags"的值),而第二个是类型构造函数在其上运行。