Reputation: 3753
I have a list of maybes and a function that gives me a node's color (if present):
maybeNeighbors :: [Maybe Node]
nodeColor :: Node -> Maybe Color
Now I'd like to map colors to nodes, and as intermediate step I want to have a list of tuples:
coloredList :: [(Color, [Node])]
(Because I'll construct a Map from it later with listToUFM_C (++) listColored
)
Here is what I have so far, it works but seems ugly:
listColored = mapMaybe (\n -> nodeColor n >>= \c -> Just (c, [n])) $ catMaybes maybeNeighbors
(using catMaybes
and mapMaybe
from Data.Maybe)
I feel like I'm missing something, that I should be able to do something like (fmap . fmap) func maybeNeighbors
, but I can't figure out how func
should look like.
Or a function like this, which I can't find either: (Maybe a -> Maybe b) -> [Maybe a] -> [Maybe b]
Edit:
I'm working on a graph coloring problem and I want a list of nodes that have the same color. Here is an example to test in GHCi:
let l = [Just (1, Just 'a'), Just (2, Just 'a'), Nothing, Just (3, Just 'b'), Just (4, Nothing)]
Upvotes: 2
Views: 798
Reputation: 16115
If I understand correctly, you're making a function [Maybe Node] -> Map Color [Node]
?
colorMap :: [Maybe Node] -> Map Color [Node]
colorMap = Map.fromListWith (++) . listColored
listColored :: [Maybe Node] -> [(Color, [Node])]
listColored = mapMaybe $ \maybeNode -> do
node <- maybeNode
color <- nodeColor node
pure (color, [node])
Edit: Isolating the listColored
part for better comparison with Fyodor's list comprehension.
Upvotes: 1
Reputation: 80754
This seems like it would be expressed the cleanest as a list comprehension:
listColored =
[ (c, [n])
| Just n <- maybeNeighbors
, Just c <- [nodeColor n]
]
Inside a list comprehension, a pattern-match failure will result in just skipping the element, so you'll naturally get rid of Nothing
s in maybeNeighbors
as well as Nothing
outputs from nodeColor
.
Upvotes: 4