containers icon indicating copy to clipboard operation
containers copied to clipboard

Add Data.Set.catMaybes and Data.Set.mapMaybe?

Open sjakobi opened this issue 8 years ago • 14 comments

The types should be the following:

catMaybes :: Ord a => Set (Maybe a) -> Set a
mapMaybe :: Ord b => (a -> Maybe b) -> Set a -> Set b

Currently I often use Set.fromList . mapMaybe f . Set.toList which I find rather tedious.

sjakobi avatar Oct 06 '16 09:10 sjakobi

Hm,

catMaybes = filter isJust
mapMaybe f = filter isJust . map f

these are a little shorter than what you've written, and don't seem too bad.

mitchellwrosen avatar Nov 12 '16 16:11 mitchellwrosen

catMaybes = filter isJust
mapMaybe f = filter isJust . map f

These would have the wrong result type (Set (Maybe a)), no?

sjakobi avatar Nov 12 '16 16:11 sjakobi

Ah - yup! Blah. Carry on then

mitchellwrosen avatar Nov 12 '16 16:11 mitchellwrosen

Can you explain more about when you need these? I'm not opposed, but would like more information.

catMaybes can be implemented efficiently using the current API:

catMaybes xs = case minView xs of Nothing -> empty Just (Nothing, xs') -> mapMonotonic fromJust xs' _ -> mapMonotonic fromJust xs

However, it's not clear to me why you would build a Set of Maybes to begin with. Set (Maybe a) ~= (Bool, Set a), but the pair representation will be more compact and usually faster when optimized.

I don't know of a way to implement mapMaybe much (if at all) better than your version.

On Oct 6, 2016 5:10 AM, "Simon Jakobi" [email protected] wrote:

The types should be the following:

catMaybes :: Ord a => Set (Maybe a) -> Set a mapMaybe :: Ord b => (a -> Maybe b) -> Set a -> Set b

Currently I often use Set.fromList . mapMaybe f . Set.toList which I find rather tedious.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/haskell/containers/issues/346, or mute the thread https://github.com/notifications/unsubscribe-auth/ABzi_T8F05uU0XGYal68rWWbjud7H_hxks5qxLsdgaJpZM4KPtm5 .

treeowl avatar Nov 12 '16 23:11 treeowl

I found a simpler version of catMaybes, using a function new in the latest version of containers:

catMaybes = mapMonotonic fromJust . dropWhileAntitone isNothing

On Nov 12, 2016 6:52 PM, "David Feuer" [email protected] wrote:

Can you explain more about when you need these? I'm not opposed, but would like more information.

catMaybes can be implemented efficiently using the current API:

catMaybes xs = case minView xs of Nothing -> empty Just (Nothing, xs') -> mapMonotonic fromJust xs' _ -> mapMonotonic fromJust xs

However, it's not clear to me why you would build a Set of Maybes to begin with. Set (Maybe a) ~= (Bool, Set a), but the pair representation will be more compact and usually faster when optimized.

I don't know of a way to implement mapMaybe much (if at all) better than your version.

On Oct 6, 2016 5:10 AM, "Simon Jakobi" [email protected] wrote:

The types should be the following:

catMaybes :: Ord a => Set (Maybe a) -> Set a mapMaybe :: Ord b => (a -> Maybe b) -> Set a -> Set b

Currently I often use Set.fromList . mapMaybe f . Set.toList which I find rather tedious.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/haskell/containers/issues/346, or mute the thread https://github.com/notifications/unsubscribe-auth/ABzi_T8F05uU0XGYal68rWWbjud7H_hxks5qxLsdgaJpZM4KPtm5 .

treeowl avatar Nov 13 '16 02:11 treeowl

Can you explain more about when you need these?

This version of mapMaybe appears a few times in stack, e.g. here, here and here.

Regarding catMaybes I think I added it in my initial request to be consistent with [], even though I can't remember ever using it. As you explained, it probably wouldn't be very useful, so I retract my request for adding it.

sjakobi avatar Nov 13 '16 19:11 sjakobi

Also missing:

Data.Sequence.mapMaybe :: (a -> Maybe b) -> Seq a -> Seq b

mitchellwrosen avatar Jun 09 '18 02:06 mitchellwrosen

I just found myself wanting mapMaybe. Even if there's no efficient way to implement it other than round-tripping through a list, it provides a nicer API for users, and is consistent with Data.Map (which has mapMaybe).

ocharles avatar Oct 28 '19 09:10 ocharles

Wouldn't it be better if Set was made an instance Filterable? Though that will introduce a new dependency: the witherable package.

srid avatar Apr 30 '20 16:04 srid

Wouldn't it be better if Set was made an instance Filterable? Though that will introduce a new dependency: the witherable package.

Set can't be, because it's not a Functor. Map k already is (the instance is defined in the witherable package). Side note: containers has to be extremely conservative about dependencies because it's an exposed GHC boot package.

treeowl avatar Apr 30 '20 16:04 treeowl

I just spent a few minutes searching for Data.Set.mapMaybe. Please add it.

isovector avatar Oct 30 '20 20:10 isovector

My concern remains: mapMaybe is O(n log n). Users tend to assume O(n). It it worth adding?

treeowl avatar Oct 30 '20 20:10 treeowl

Add a comment?

isovector avatar Oct 30 '20 20:10 isovector

Okay, fine.

treeowl avatar Oct 30 '20 20:10 treeowl