简体   繁体   English

Haskell-自定义数据类型

[英]Haskell-Custom data types

I need some advice on how to return a list of chapter names that do not contain text blocks (Text) in their type list [Article]我需要一些关于如何返回类型列表中不包含文本块(Text)的章节名称列表的建议[Article]

data Article = Text String
             | Section String [Article] deriving (Show)

myArticle :: Article
myArticle = Section "Document" [
                 Section "Introduction" [
                       Text "My intoduction",
                       Section "Notation" [Text "alpha beta gamma"]],
                 Section "Methods" [
                       Section "Functional Programming" [Text "FPR"],
                       Section "Logical Programming" [Text "LPR"]],
                 Section "Results" [Text "All is great"]]
names :: Article -> [String]

Expected output:预计 output:

names myArticle = ["Document", "Methods"]

I tried the basic functions:我尝试了基本功能:

names :: Article -> [String]

Always start by observing the structure of your datatype:始终从观察数据类型的结构开始:

                     Section
                   /        \
                Text        Section
                            /   |  \
                         Text Text  Text

You can see that this is a tree.你可以看到这是一棵树。 Thus we start by deconstructing this tree in names:因此,我们首先在名称中解构这棵树:

names :: Article -> [String]
names a = case a of
  Text _ -> []
  Section chptr xs -> []

We only want to return chptr if none of it's childs in the list xs is text.如果列表xs中的子项都不是文本,我们只想返回chptr Thus we need a function to know whether something is text:因此我们需要一个 function 来判断是否是文本:

isText :: Article -> Bool
isText (Text _) = True
isText _ = False

Now looking at names we can use the built-in any:: (a -> Bool) -> [a] -> Bool function to return chptr, if none of it's childs is text:现在查看names ,我们可以使用内置的any:: (a -> Bool) -> [a] -> Bool function 返回 chptr,如果它的子项都不是文本:

names :: Article -> [String]
names a = case a of
  Text _ -> []
  Section chptr xs -> 
    (if any isText xs then [] else [chptr]) 

But names only returns the first chapter name.names只返回第一章名称。 We already concluded this is a tree, and processing these in Haskell is usually done recursively.我们已经断定这是一棵树,在 Haskell 中处理这些通常是递归完成的。 So we must call names again on our list xs of sections, and add the result to the names we already found:所以我们必须在我们的部分列表xs上再次调用名称,并将结果添加到我们已经找到的名称中:

names :: Article -> [String]
names a = case a of
  Text _ -> []
  Section chptr xs -> 
    (if any isText xs then [] else [chptr]) ++ concatMap names xs 

voila!瞧!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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