【问题标题】:How to do recursion for recursive data type in function in Haskell如何在 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 添加到结果中。

标签: haskell recursion


【解决方案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。但我们不能只使用mapmenu 而不是content,因为内容是Pages 的列表。这意味着我们有一个递归数据类型列表。所以我们使用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-24
    • 2016-09-20
    • 2011-02-14
    • 2019-02-28
    • 1970-01-01
    • 2015-05-25
    • 2021-08-10
    • 2018-08-15
    相关资源
    最近更新 更多