简体   繁体   English

如何对 Haskell 中的 function 中的递归数据类型进行递归

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM