2

I would like to create a function that Prints out every Palindrome from a given List as a List itself.

isPalindrome :: String -> Bool
isPalindrome w = w == reverse w

somefunction :: String -> String
somefunction input = if isPalindrome (input) == True then input else ""

printPalindromes xs = map somefunction (xs)

Almost does the job but if we try

*Main> printPalindromes ["anna","peter","aa","bb","cc","efg"]
              result -> ["anna","","aa","bb","cc",""]

what we would actually like as result is this: result -> ["anna","aa","bb","cc"]

As you can see the function somefunction just returns "" if the given input is not a palindrome. How do I actually do nothing during the else case in somefunction?

Is there a more nice and more compact way to reach my goal?

D idsea J
  • 103
  • 1
  • 8
  • 1
    Try using `filter` rather than `map`. (Then you will find that `somefunction` is irrelevant, all you need is `isPalindrome`.) – Robin Zigmond Jan 24 '20 at 22:31
  • Yes using filter seems like a good idea. I wonder how to do it without using filter just to play around with functions (I'm super new to Haskell) – D idsea J Jan 24 '20 at 22:38
  • 1
    You can't do it with `map`, which among other things guarantees that it cannot grow, shrink, or reorder the elements in its argument, only apply a function to each value. `foldr` is universal, in the sense that you can implement both `map` and `filter` (among other functions) using `foldr`. – chepner Jan 24 '20 at 23:02
  • 1
    you can't do that with `map` *alone*, but [if you stick a `zip` before it](https://stackoverflow.com/a/11951590/849891), or a `concat` after it, then you can. map...zip... lets us define scanl/unfold/iterate, and concat...map... lets us define filter. – Will Ness Jan 26 '20 at 10:25

1 Answers1

7

You filter the list, and remove all the elements that are empty lists. You can use the null :: [a] -> Bool function for that:

filterPalindromes :: [String] -> [String]
filterPalindromes = filter (not . null) . map somefunction

It however might make more sense to here use your isPalindrom function directly, especially since if the input is the empty string, then this is a palindrome:

filterPalindromes :: [String] -> [String]
filterPalindromes = filter isPalindrome
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555