Skip to content

Commit 35c3945

Browse files
Tom HardingLiamGoodacre
authored andcommitted
Add extra defaults for partition and filter (#10)
This commit adds four new functions: `partitionDefaultFilter`, `partitionDefaultFilterMap`, `filterDefaultPartition`, and `filterDefaultPartitionMap`.
1 parent 9c50746 commit 35c3945

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

src/Data/Filterable.purs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ module Data.Filterable
66
, filter
77
, eitherBool
88
, partitionDefault
9+
, partitionDefaultFilter
10+
, partitionDefaultFilterMap
911
, maybeBool
1012
, filterDefault
13+
, filterDefaultPartition
14+
, filterDefaultPartitionMap
1115
, partitioned
1216
, filtered
1317
, cleared
@@ -19,9 +23,10 @@ import Data.Array (partition, mapMaybe, filter) as Array
1923
import Data.Either (Either(..))
2024
import Data.Foldable (foldl, foldr)
2125
import Data.Functor (class Functor)
26+
import Data.HeytingAlgebra (not)
2227
import Data.List (List(..), filter, mapMaybe) as List
23-
import Data.Maybe (Maybe(..))
2428
import Data.Map (Map, empty, insert, alter, toUnfoldable) as Map
29+
import Data.Maybe (Maybe(..))
2530
import Data.Monoid (class Monoid, mempty)
2631
import Data.Semigroup ((<>))
2732
import Data.Tuple (Tuple(..))
@@ -60,23 +65,49 @@ eitherBool :: forall a.
6065
(a -> Boolean) -> a -> Either a a
6166
eitherBool p x = if p x then Right x else Left x
6267

68+
-- | Upgrade a boolean-style predicate to a maybe-style predicate mapping.
69+
maybeBool :: forall a.
70+
(a -> Boolean) -> a -> Maybe a
71+
maybeBool p x = if p x then Just x else Nothing
72+
6373
-- | A default implementation of `partition` using `partitionMap`.
6474
partitionDefault :: forall f a. Filterable f =>
6575
(a -> Boolean) -> f a -> { no :: f a, yes :: f a }
6676
partitionDefault p xs =
6777
let o = partitionMap (eitherBool p) xs
6878
in {no: o.left, yes: o.right}
6979

70-
-- | Upgrade a boolean-style predicate to a maybe-style predicate mapping.
71-
maybeBool :: forall a.
72-
(a -> Boolean) -> a -> Maybe a
73-
maybeBool p x = if p x then Just x else Nothing
80+
-- | A default implementation of `partition` using `filter`. Note that this is
81+
-- | almost certainly going to be suboptimal compared to direct implementations.
82+
partitionDefaultFilter :: forall f a. Filterable f =>
83+
(a -> Boolean) -> f a -> { no :: f a, yes :: f a }
84+
partitionDefaultFilter p xs = { yes: filter p xs, no: filter (not p) xs }
85+
86+
-- | A default implementation of `partition` using `filterMap`. Note that this
87+
-- | is almost certainly going to be suboptimal compared to direct
88+
-- | implementations.
89+
partitionDefaultFilterMap :: forall f a. Filterable f =>
90+
(a -> Boolean) -> f a -> { no :: f a, yes :: f a }
91+
partitionDefaultFilterMap p xs =
92+
{ yes: filterMap (maybeBool p) xs
93+
, no: filterMap (maybeBool (not p)) xs
94+
}
7495

7596
-- | A default implementation of `filter` using `filterMap`.
7697
filterDefault :: forall f a. Filterable f =>
7798
(a -> Boolean) -> f a -> f a
7899
filterDefault = filterMap <<< maybeBool
79100

101+
-- | A default implementation of `filter` using `partition`.
102+
filterDefaultPartition :: forall f a. Filterable f =>
103+
(a -> Boolean) -> f a -> f a
104+
filterDefaultPartition p xs = (partition p xs).yes
105+
106+
-- | A default implementation of `filter` using `partitionMap`.
107+
filterDefaultPartitionMap :: forall f a. Filterable f =>
108+
(a -> Boolean) -> f a -> f a
109+
filterDefaultPartitionMap p xs = (partitionMap (eitherBool p) xs).right
110+
80111
partitioned :: forall f l r. Filterable f =>
81112
f (Either l r) -> { left :: f l, right :: f r }
82113
partitioned = partitionMap id
@@ -174,4 +205,3 @@ instance filterableMap :: Ord k => Filterable (Map.Map k) where
174205
select (Tuple k x) m = Map.alter (const (p x)) k m
175206

176207
filter p = filterDefault p
177-

0 commit comments

Comments
 (0)