Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there better ways to do Map k [v] -> Maybe (Map k v)?

Tags:

haskell

I want to create a function that turns Map k [v] (Data.Map.Strict) into Maybe (Map k v).

What it does is this:

  • If any of the lists doesn't have exactly one element, the function returns Nothing.
  • If all of the lists have exactly one element, it returns the expected map wrapped in a Just.

The only thing I can think of is to do this manually with foldrWithKey' or foldlWithKey'. Are there better ways?

like image 763
haskellHQ Avatar asked Nov 20 '16 21:11

haskellHQ


1 Answers

You are looking for traverse :: (Traverseable t, Applicative f) => (a -> f b) -> t a -> f (t b) from Data.Traversable (but also in the Prelude).

justOne :: [a] -> Maybe a
justOne [x] = Just x
justOne _ = Nothing

allJustOne :: Map k [v] -> Maybe (Map k v)
allJustOne = traverse justOne

traverse f is probably best understood as sequenceA . fmap f. sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a) on the other hand is a way of pulling the applicative "effects" out of a Traversable structure. For example one might execute a list of IO actions with sequenceA :: [IO a] -> IO [a]. Or in the case of Maybe the result will be Just if all the elements in the Traversable structure are Just and if any of the elements is Nothing the result of sequenceA will also be Nothing.

If you know sequence or mapM, sequenceA and traverse are just generalisations of those.

like image 168
Julia Path Avatar answered Sep 27 '22 20:09

Julia Path