[英]How to do recursion for recursive data type in function in Haskell
I am trying to implement menu
function that returns all titles from custom data type Page
我正在尝试实现从自定义数据类型
Page
返回所有标题的menu
function
data Page = Text String
| Title String [Page] deriving(Show)
menu :: Page -> [String]
menu (Text a) = []
menu (Title name content ) = [name]
But I want also this function will work also for some "hierarchy" of pages, for example, like in index
:但我也想要这个 function 也适用于页面的一些“层次结构”,例如,像
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"]]
I done some functions for this, but I have no idea how to start recursion for "hierarchy" Page
我为此做了一些功能,但我不知道如何开始递归“层次结构”
Page
menu :: Page -> [String]
menu (Text a) = []
menu (Title name content ) = [name]
The output is output 是
*Main> menu index
["Home"]
But can I do list of all Title
in index
?但是我可以列出
index
中的所有Title
吗?
Thanks a lot in advance for answer!非常感谢您的回答!
One way to do it is as follows:一种方法如下:
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
A small test:一个小测试:
λ> menu index
["Home","Welcome!","Hello World!","Lorem","ipsum","dolor","no title","Haskell","Look!","test","Finish","It will be look great"]
We are using concatMap
.我们正在使用
concatMap
。
Since Text a
is a leaf, we return the extracted a
which is its String
in a list as [a]
.由于
Text a
是叶子,我们将提取a
作为[a]
返回列表中的字符串,它是它的String
。
Title name content
has 2 parts. Title name content
有 2 个部分。 name
is just a string, so we add it to the list and recursively call menu
. name
只是一个字符串,所以我们将它添加到列表中并递归调用menu
。 But we can't just map
menu
over content
, since content is a list of Page
s.但是我们不能只是
map
menu
over content
,因为 content 是Page
的列表。 That means that we have a list of recursive data types.这意味着我们有一个递归数据类型列表。 So we use
concatMap
that just concatenates the lists that are produced by each Page
in the list.所以我们使用
concatMap
来连接列表中每个Page
生成的列表。
If you like to keep track of whether a string was a Title
or a Text
:如果您想跟踪字符串是
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.