Reputation: 2330
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
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