Lukasko
Lukasko

Reputation: 23

Haskell-Custom data structure from an array

I need some advice on how to list only words from Text branches in this code I have programmed.

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"]]

tex :: Article -> [String]
tex (Text x) = [x]
tex (Section x (l:ls)) = tex l

I tried to call ls in the tex function, but it throws me an error. I don't know how to proceed.

Upvotes: 0

Views: 163

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477641

You pattern match with (l:ls), which means it is a non-empty list, and you only work with l, so the first item, you "ignore" the rest of the Articles (which can be Texts and Sections).

You can match with any list, and then have to process that list by generating a list of Strings for each subitem, and concatenating these, so:

tex :: Article -> [String]
tex (Text x) = [x]
tex (Section _ ls) = … ls

Upvotes: 1

You're looking for the concatMap function. This will run the function you give it on each element of the input list, and concatenate all of the results together into a single list. Also, you don't need to use : to bind a list unless you actually want to break it into its head and tail (and in your case, you don't). So change the last line of your code to this:

tex (Section x ls) = concatMap tex ls

And then tex myArticle will be ["My intoduction","alpha beta gamma","FPR","LPR","All is great"].

Upvotes: 4

Related Questions