I'm learning Haskell on my own, and I'm wondering if this is idiomatic Haskell.

In particular: is it a common pattern to "wrap" the result in a list in order to make a function total? (that's what I ended up doing to ensure the function was total and no compiler warnings about not matching a pattern).

safeHead :: [a] -> Maybe a
safeHead []     = Nothing
safeHead (x:_)  = Just x

firstLetters :: [String] -> [Char]
firstLetters ss = concat $
                     map (\s -> case safeHead s of
                                Nothing -> []
                                Just c  -> [c]) ss
| improve this question | | | | |

Well a few thoughts, of all String = [Char] so we could really give the signature

firstLetters :: [String] -> String

Whether you think this is better is a matter of taste. Second, you should take a look at

Data.Maybe.mapMaybe :: (a -> Maybe b) -> [a] -> [b]

It's exactly what you'd expect, it applies a function to Maybes and prunes out the Nothings. This simplifies the slightly ugly concat bit.

 firstLetters = mapMaybe safeHead

Much clearer :) In the interest of teaching you to fish, here's how I found the name of mapMaybe

| improve this answer | | | | |
  • \$\begingroup\$ When you say "is a matter of taste" is that a 50/50 divide in the Haskell community, or more like a 90/10 towards using String? \$\endgroup\$ – j-a Nov 20 '14 at 5:24
  • \$\begingroup\$ @j-a 50/50. In general you should prefer String when you're using well strings. In all other cases it's entirely up to you! \$\endgroup\$ – Daniel Gratzer Nov 20 '14 at 6:02

In addition to @jozefg's answer, Data.Maybe also contains listToMaybe.

listToMaybe :: [a] -> Maybe a

The listToMaybe function returns Nothing on an empty list or Just a where a is the first element of the list.

Which reduces the code to

firstLetters = mapMaybe listToMaybe
| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.