如何解决递归数据类型的其他情况
我目前正在学习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
的意思),您创建的不是单个账单,而是它们的列表,这似乎没有用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。