递归数据类型的其他情况

问题描述

我目前正在学习Haskell,我想为Dollar货币(只是账单,而不是硬币)定义自己的递归数据类型。

我的尝试看起来像这样:

data Dollar = One Dollar
             | Two Dollar
             | Five Dollar
             | Ten Dollar
             | Twenty Dollar
             | Fifty Dollar
             | Hundred Dollar

我给我的一个朋友看了这个,他说看起来不错,但是他还告诉我在定义的末尾加上| End。他试图解释为什么有必要,但我无法理解他的思路。也许有人在这里有我可以理解的解释。我真的很感激。

解决方法

您的朋友可能表示某个时候您需要一个基本案例。给定定义

data Dollar = One Dollar
            | Two Dollar
            | Five Dollar
            | Ten Dollar
            | Twenty Dollar
            | Fifty Dollar
            | Hundred Dollar
            | End

您可以将任意数量的金额表示为Dollar值的链接列表,每个值表示一个帐单和该金额的“其余”。 End将终止列表。例如,

fortyTwoDollars :: Dollar
fortyTwoDollars = Twenty (Ten (Five (Five (Two End))))

但是,我看不出将列表混入其中的理由;一个单独的Dollar值可以代表一个账单,您可以使用一个[Dollar]值来表示一个托收。

data Dollar = One
            | Two
            | Five
            | Ten
            | Twenty
            | Fifty
            | Hundred
            
fortyTwoDollars :: [Dollar]
fortyTwoDollars = [Twenty,Ten,Five,Two]
,

这不需要递归

描述帐单的问题不需要递归类型。让我们从列表开始,然后谈论您的“美元”。

列表

您的账单基本上是特殊的清单,具有更多的构造函数且没有终止。例如,普通列表如下:

address

这意味着我们可以构建一个链接列表,例如:

data List a = SomeElement a List | End

但是,如果我们没有myList = SomeElement 1 (SomeElement 2 ( End ) ) ,我们将无法停止该列表。它必须永远End

SomeElement

返回“美元”

因此,您有这个特殊的美元清单。您可以使用otherList = SomeElement 1 (SomeElement 2 ( ... oh no,I have to keep going! ...)) SomeElement 1来代替使用SomeElement 5来换一美元和使用One来换五美元的钞票。这使您可以构造一个“堆栈”票据:

Five

但是您无法停止,除非您进行列表循环,例如将myMoney = One (Two (Five ( One ... 设为...,从而得到myMoney的无限列表。

质疑设计

您可能只想简单一些:

One Two Five One One Two Five One One ...

然后,您可以使用诸如data Dollar = One | Two | Five 之类的普通清单制作一个美元清单(类型[Dollar])。声称[One,Two,One]账单还包含另一美元(这就是One的意思),您创建的不是单个账单,而是它们的列表,这似乎没有用。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...