如何在 Haskell 函数中对递归数据类型进行递归
Posted
技术标签:
【中文标题】如何在 Haskell 函数中对递归数据类型进行递归【英文标题】:How to do recursion for recursive data type in function in Haskell 【发布时间】:2022-01-06 19:00:42 【问题描述】:我正在尝试实现 menu
函数,该函数返回来自自定义数据类型 Page
的所有标题
data Page = Text String
| Title String [Page] deriving(Show)
menu :: Page -> [String]
menu (Text a) = []
menu (Title name content ) = [name]
但我也希望此功能也适用于某些“层次结构”的页面,例如index
:
index = Title "Home" [
Title "Welcome!"[
Text "Hello World!",
Title "Lorem"[Text "ipsum"]],
Title "dolor"[
Title "no title" [Text "Haskell"],
Title "Look!" [Text "test"]],
Title "Finish" [Text "It will be look great"]]
我为此做了一些函数,但我不知道如何开始递归“层次结构”Page
menu :: Page -> [String]
menu (Text a) = []
menu (Title name content ) = [name]
输出是
*Main> menu index
["Home"]
但是我可以列出index
中的所有Title
吗?
非常感谢您的回答!
【问题讨论】:
你有一个页面列表;在上面映射menu
,你会得到一个列表列表。连接这些列表,然后将 name
添加到结果中。
【参考方案1】:
一种方法如下:
data Page = Text String
| Title String [Page] deriving(Show)
menu :: Page -> [String]
menu (Text a) = [a]
menu (Title name content) = name : concatMap menu content
data Page = Text String
| Title String [Page] deriving(Show)
menu :: Page -> [String]
menu (Text a) = [a]
menu (Title name content) = name : concatMap menu content
一个小测试:
λ> menu index
["Home","Welcome!","Hello World!","Lorem","ipsum","dolor","no title","Haskell","Look!","test","Finish","It will be look great"]
我们正在使用concatMap
。
由于Text a
是一个叶子,我们将提取的a
返回为[a]
列表中的String
。
Title name content
有 2 个部分。 name
只是一个字符串,所以我们将它添加到列表中并递归调用menu
。但我们不能只使用map
menu
而不是content
,因为内容是Page
s 的列表。这意味着我们有一个递归数据类型列表。所以我们使用concatMap
,它只是连接列表中每个Page
生成的列表。
如果您想跟踪字符串是Title
还是Text
:
data Page = Text String
| Title String [Page] deriving(Show)
menu :: Page -> [String]
menu (Text a) = ["Text " ++ a]
menu (Title name content) = ("Title " ++ name) : concatMap menu content
【讨论】:
以上是关于如何在 Haskell 函数中对递归数据类型进行递归的主要内容,如果未能解决你的问题,请参考以下文章