-
Notifications
You must be signed in to change notification settings - Fork 187
Add mapMaybe to sets and Seq
#1159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Thank you for the PR! @treeowl, would you agree? |
|
I also don't think we really need traverseMaybe :: Applicative f => (a -> f (Maybe b)) -> Whatever a -> f (Whatever b) |
|
And what about |
That's a good question, but there's a problem since we are doing a tail-recursive construction with an accumulator. To keep the same style, we need I'm fine with considering this later, doesn't have to be in this PR. |
|
Thanks for the comments, will get to them at some point.
|
|
For Also, I still want |
|
To clarify, |
|
Sorry, I seem to have half-remembered some bits. I need to look through again. |
|
I think I've resolved all the comments above, except I didn't add |
I did do a benchmark, and a dedicated diff --git a/containers-tests/benchmarks/Set.hs b/containers-tests/benchmarks/Set.hs
index 9e367391..6708cba6 100644
--- a/containers-tests/benchmarks/Set.hs
+++ b/containers-tests/benchmarks/Set.hs
@@ -7,6 +7,7 @@ import Control.Exception (evaluate)
import Test.Tasty.Bench (bench, bgroup, defaultMain, whnf)
import Data.List (foldl')
import qualified Data.Set as S
+import qualified Data.Set.Internal as S
import Utils.Fold (foldBenchmarks)
import Utils.Random (shuffle)
@@ -16,6 +17,7 @@ main = do
s_even = S.fromList elems_even :: S.Set Int
s_odd = S.fromList elems_odd :: S.Set Int
strings_s = S.fromList strings
+ s_maybe = S.insert Nothing $ S.map Just s
evaluate $ rnf [s, s_even, s_odd]
evaluate $ rnf
[elems_distinct_asc, elems_distinct_desc, elems_asc, elems_desc]
@@ -68,6 +70,8 @@ main = do
, bench "eq" $ whnf (\s' -> s' == s') s -- worst case, compares everything
, bench "compare" $ whnf (\s' -> compare s' s') s -- worst case, compares everything
, bgroup "folds" $ foldBenchmarks S.foldr S.foldl S.foldr' S.foldl' foldMap s
+ , bench "catMaybes1" $ whnf S.catMaybes1 s_maybe
+ , bench "catMaybes2" $ whnf S.catMaybes2 s_maybe
]
where
bound = 2^12
diff --git a/containers/src/Data/Set/Internal.hs b/containers/src/Data/Set/Internal.hs
index 0af7eb15..a330491f 100644
--- a/containers/src/Data/Set/Internal.hs
+++ b/containers/src/Data/Set/Internal.hs
@@ -163,6 +163,8 @@ module Data.Set.Internal (
, dropWhileAntitone
, spanAntitone
, mapMaybe
+ , catMaybes1
+ , catMaybes2
, partition
, split
, splitMember
@@ -231,6 +233,7 @@ module Data.Set.Internal (
import Utils.Containers.Internal.Prelude hiding
(filter,foldl,foldl',foldr,null,map,take,drop,splitAt)
+import qualified Data.Maybe as Maybe
import Prelude ()
import Control.Applicative (Const(..))
import qualified Data.List as List
@@ -1011,6 +1014,13 @@ mapMaybe f t = finishB (foldl' go emptyB t)
Just x' -> insertB x' b
{-# INLINABLE mapMaybe #-}
+catMaybes1, catMaybes2 :: Ord a => Set (Maybe a) -> Set a
+{-# INLINABLE catMaybes1 #-}
+{-# INLINABLE catMaybes2 #-}
+
+catMaybes1 = mapMaybe id
+catMaybes2 = mapMonotonic Maybe.fromJust . dropWhileAntitone Maybe.isNothing
+
{----------------------------------------------------------------------
Map
----------------------------------------------------------------------}I get I still don't feel strongly about including it. |
meooow25
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, just a couple of minor comments.
I did do a benchmark, and a dedicated catMaybes can indeed be more efficient.
That's a good point about Set, since Nothing will always be the minimum value.
I still don't feel strongly about including it.
I agree, if someone really wants this we can consider adding it later.
|
Thanks, updated. |
catMaybes and mapMaybe to sets, maps and SeqmapMaybe to sets, maps and Seq
mapMaybe to sets, maps and SeqmapMaybe to sets and Seq
meooow25
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks!
As discussed in #346. We now have
mapMaybein all ofSeq,Set,IntSet, strict and lazyMap, and strict and lazyIntMap.AndThe issue doesn't mention all of them, but I figured it would be good to have a consistent API.catMaybesin all of those exceptIntSet(where it doesn't make sense).