John Smith
John Smith

Reputation: 2330

How to conditionally insert elements into list?

Say I have a list of Strings

["hello", "xbox", "blue"]

And now I want to "insert" (as in create a new immutable list) linefeed characters into the list, but only if the word before ends on a vowel, e.g. a function that creates the following list:

["hello", "\n", "xbox", "blue", "\n"]

What's the most elegant/direct way of doing this in haskell?

Upvotes: 0

Views: 593

Answers (1)

AJF
AJF

Reputation: 11923

One way of doing this would be using do-notation. do-notation on the list monad is a lot like list comprehension, but it also allows you to 'return' multiple elements. Here's my implementation:

solution1 :: [String] -> [String]
solution1 strings = do
    str <- strings   -- Go through each element of the list
    if last str `elem` "aeiou"
        then [str, "\n"]   -- 'Replace' that element with the element then a newline
        else [str]         -- Do nothing.

But this is a bit of a weird way of going about things, especially if you're a beginner. The usual way would be recursion, so let's do that instead:

solution2 :: [String] -> [String]
solution2 []     = [] -- Base case: empty list.
solution2 (x:xs) =    -- Inductive case: non-empty list.
    if last x `elem` "aeiou"
        then x : "\n" : solution2 xs -- Recur, reconstructing as we go.
        else x : solution2 xs        -- Recur, this time with no extra newline.

In reality though, these do basically the same thing—do-notation on lists is basically just an abstraction of the second method.

Something to consider: I used the last function, but this will fail on empty strings. How could you fix that?

Upvotes: 2

Related Questions