Skip to content
This repository was archived by the owner on Oct 4, 2020. It is now read-only.

Commit 6620634

Browse files
committed
Added toAscUnfoldable in place of toAscList
1 parent 7a6cd51 commit 6620634

File tree

2 files changed

+44
-32
lines changed

2 files changed

+44
-32
lines changed

src/Data/Map.purs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ module Data.Map
1919
, fromFoldable
2020
, fromFoldableWith
2121
, toList
22-
, toAscList
2322
, toUnfoldable
23+
, toAscUnfoldable
2424
, delete
2525
, pop
2626
, member
@@ -36,15 +36,13 @@ module Data.Map
3636
) where
3737

3838
import Prelude
39-
4039
import Data.Foldable (foldl, foldMap, foldr, class Foldable)
4140
import Data.List (List(..), (:), length, nub)
4241
import Data.Maybe (Maybe(..), maybe, isJust, fromMaybe)
4342
import Data.Monoid (class Monoid)
4443
import Data.Traversable (traverse, class Traversable)
4544
import Data.Tuple (Tuple(Tuple), snd)
4645
import Data.Unfoldable (class Unfoldable, unfoldr)
47-
4846
import Partial.Unsafe (unsafePartial)
4947

5048
-- | `Map k v` represents maps from keys of type `k` to values of type `v`.
@@ -53,14 +51,18 @@ data Map k v
5351
| Two (Map k v) k v (Map k v)
5452
| Three (Map k v) k v (Map k v) k v (Map k v)
5553

54+
-- Internal use
55+
toAscArray :: forall k v. Map k v -> Array (Tuple k v)
56+
toAscArray = toAscUnfoldable
57+
5658
instance eqMap :: (Eq k, Eq v) => Eq (Map k v) where
57-
eq m1 m2 = toAscList m1 == toAscList m2
59+
eq m1 m2 = toAscArray m1 == toAscArray m2
5860

5961
instance ordMap :: (Ord k, Ord v) => Ord (Map k v) where
60-
compare m1 m2 = compare (toAscList m1) (toAscList m2)
62+
compare m1 m2 = compare (toAscArray m1) (toAscArray m2)
6163

6264
instance showMap :: (Show k, Show v) => Show (Map k v) where
63-
show m = "(fromList " <> show (toAscList m) <> ")"
65+
show m = "(fromFoldable " <> show (toAscArray m) <> ")"
6466

6567
instance semigroupMap :: Ord k => Semigroup (Map k v) where
6668
append = union
@@ -381,13 +383,7 @@ fromFoldableWith f = foldl (\m (Tuple k v) -> alter (combine v) k m) empty where
381383

382384
-- | Convert a map to a list of key/value pairs
383385
toList :: forall k v. Map k v -> List (Tuple k v)
384-
toList Leaf = Nil
385-
toList (Two left k v right) = toList left <> Tuple k v : toList right
386-
toList (Three left k1 v1 mid k2 v2 right) = toList left <> Tuple k1 v1 : toList mid <> Tuple k2 v2 : toList right
387-
388-
-- | Convert a map to a list of key/value pairs where the keys are in ascending order
389-
toAscList :: forall k v. Map k v -> List (Tuple k v)
390-
toAscList = toList
386+
toList = toUnfoldable
391387

392388
-- | Convert a map to an unfoldable structure of key/value pairs
393389
toUnfoldable :: forall f k v. Unfoldable f => Map k v -> f (Tuple k v)
@@ -400,6 +396,21 @@ toUnfoldable m = unfoldr go (m : Nil) where
400396
Three left k1 v1 mid k2 v2 right ->
401397
Just $ Tuple (Tuple k1 v1) (singleton k2 v2 : left : mid : right : tl)
402398

399+
-- | Convert a map to an unfoldable structure of key/value pairs where the keys are in ascending order
400+
toAscUnfoldable :: forall f k v. Unfoldable f => Map k v -> f (Tuple k v)
401+
toAscUnfoldable m = unfoldr go (m : Nil) where
402+
go Nil = Nothing
403+
go (hd : tl) = case hd of
404+
Leaf -> go tl
405+
Two Leaf k v Leaf ->
406+
Just $ Tuple (Tuple k v) tl
407+
Two Leaf k v right ->
408+
Just $ Tuple (Tuple k v) (right : tl)
409+
Two left k v right ->
410+
go $ left : singleton k v : right : tl
411+
Three left k1 v1 mid k2 v2 right ->
412+
go $ left : singleton k1 v1 : mid : singleton k2 v2 : right : tl
413+
403414
-- | Get a list of the keys contained in a map
404415
keys :: forall k v. Map k v -> List k
405416
keys Leaf = Nil

test/Test/Data/Map.purs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
module Test.Data.Map where
22

33
import Prelude
4-
4+
import Data.List.NonEmpty as NEL
5+
import Data.Map as M
56
import Control.Alt ((<|>))
67
import Control.Monad.Eff (Eff)
78
import Control.Monad.Eff.Console (log, CONSOLE)
89
import Control.Monad.Eff.Exception (EXCEPTION)
910
import Control.Monad.Eff.Random (RANDOM)
10-
1111
import Data.Foldable (foldl, for_, all)
1212
import Data.Function (on)
13-
import Data.List (List(..), groupBy, length, nubBy, sortBy, singleton)
14-
import Data.List.NonEmpty as NEL
15-
import Data.Map as M
13+
import Data.List (List(Cons), groupBy, length, nubBy, singleton, sort, sortBy)
1614
import Data.Maybe (Maybe(..), fromMaybe)
1715
import Data.Tuple (Tuple(..), fst)
18-
1916
import Partial.Unsafe (unsafePartial)
20-
2117
import Test.QuickCheck ((<?>), (===), quickCheck, quickCheck')
2218
import Test.QuickCheck.Arbitrary (class Arbitrary, arbitrary)
2319

@@ -194,21 +190,26 @@ mapTests = do
194190
quickCheck (M.lookup 1 nums == Just 2 <?> "invalid lookup - 1")
195191
quickCheck (M.lookup 2 nums == Nothing <?> "invalid lookup - 2")
196192

197-
log "toList . fromFoldable = id"
198-
quickCheck $ \arr -> let f x = M.toList (M.fromFoldable x)
199-
in f (f arr) == f (arr :: List (Tuple SmallKey Int)) <?> show arr
193+
log "sort . toList . fromFoldable = sort (on lists without key-duplicates)"
194+
quickCheck $ \(list :: List (Tuple SmallKey Int)) ->
195+
let nubbedList = nubBy ((==) `on` fst) list
196+
f x = M.toList (M.fromFoldable x)
197+
in sort (f nubbedList) == sort nubbedList <?> show nubbedList
200198

201199
log "fromFoldable . toList = id"
202-
quickCheck $ \(TestMap m) -> let f m' = M.fromFoldable (M.toList m') in
203-
M.toList (f m) == M.toList (m :: M.Map SmallKey Int) <?> show m
200+
quickCheck $ \(TestMap (m :: M.Map SmallKey Int)) ->
201+
let f m' = M.fromFoldable (M.toList m')
202+
in f m == m <?> show m
204203

205204
log "fromFoldable . toUnfoldable = id"
206-
quickCheck $ \(TestMap m) -> let f m' = M.fromFoldable (M.toUnfoldable m' :: List (Tuple SmallKey Int)) in
207-
f m == (m :: M.Map SmallKey Int) <?> show m
205+
quickCheck $ \(TestMap (m :: M.Map SmallKey Int)) ->
206+
let f m' = M.fromFoldable (M.toUnfoldable m' :: List (Tuple SmallKey Int))
207+
in f m == m <?> show m
208208

209209
log "fromFoldableWith const = fromFoldable"
210-
quickCheck $ \arr -> M.fromFoldableWith const arr ==
211-
M.fromFoldable (arr :: List (Tuple SmallKey Int)) <?> show arr
210+
quickCheck $ \arr ->
211+
M.fromFoldableWith const arr ==
212+
M.fromFoldable (arr :: List (Tuple SmallKey Int)) <?> show arr
212213

213214
log "fromFoldableWith (<>) = fromFoldable . collapse with (<>) . group on fst"
214215
quickCheck $ \arr ->
@@ -218,10 +219,10 @@ mapTests = do
218219
groupBy ((==) `on` fst) <<< sortBy (compare `on` fst) in
219220
M.fromFoldableWith (<>) arr === f (arr :: List (Tuple String String))
220221

221-
log "toAscList is sorted version of toList"
222+
log "toAscUnfoldable is sorted version of toUnfoldable"
222223
quickCheck $ \(TestMap m) ->
223-
let list = M.toList (m :: M.Map SmallKey Int)
224-
ascList = M.toAscList m
224+
let list = M.toUnfoldable (m :: M.Map SmallKey Int)
225+
ascList = M.toAscUnfoldable m
225226
in ascList === sortBy (compare `on` fst) list
226227

227228
log "Lookup from union"

0 commit comments

Comments
 (0)