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

Prepare for 2.0 release #73

Merged
merged 1 commit into from
Oct 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
"package.json"
],
"dependencies": {
"purescript-arrays": "^1.0.0",
"purescript-functions": "^1.0.0",
"purescript-lists": "^1.0.0",
"purescript-st": "^1.0.0"
"purescript-arrays": "^3.0.0",
"purescript-functions": "^2.0.0",
"purescript-lists": "^3.0.0",
"purescript-st": "^2.0.0"
},
"devDependencies": {
"purescript-quickcheck": "^1.0.0"
"purescript-quickcheck": "^3.0.0"
}
}
38 changes: 19 additions & 19 deletions src/Data/Map.purs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ module Data.Map
, fromFoldable
, fromFoldableWith
, toList
, fromList
, fromListWith
, toUnfoldable
, delete
, pop
, member
Expand All @@ -38,11 +37,12 @@ module Data.Map
import Prelude

import Data.Foldable (foldl, foldMap, foldr, class Foldable)
import Data.List (List(..), length, nub)
import Data.List (List(..), (:), length, nub)
import Data.Maybe (Maybe(..), maybe, isJust, fromMaybe)
import Data.Monoid (class Monoid)
import Data.Traversable (traverse, class Traversable)
import Data.Tuple (Tuple(..), uncurry, snd)
import Data.Unfoldable (class Unfoldable, unfoldr)

import Partial.Unsafe (unsafePartial)

Expand All @@ -55,16 +55,16 @@ data Map k v
instance eqMap :: (Eq k, Eq v) => Eq (Map k v) where
eq m1 m2 = toList m1 == toList m2

instance showMap :: (Show k, Show v) => Show (Map k v) where
show m = "(fromList " <> show (toList m) <> ")"

instance ordMap :: (Ord k, Ord v) => Ord (Map k v) where
compare m1 m2 = compare (toList m1) (toList m2)

instance semigroupMap :: (Ord k) => Semigroup (Map k v) where
instance showMap :: (Show k, Show v) => Show (Map k v) where
show m = "(fromList " <> show (toList m) <> ")"

instance semigroupMap :: Ord k => Semigroup (Map k v) where
append = union

instance monoidMap :: (Ord k) => Monoid (Map k v) where
instance monoidMap :: Ord k => Monoid (Map k v) where
mempty = empty

instance functorMap :: Functor (Map k) where
Expand All @@ -77,7 +77,7 @@ instance foldableMap :: Foldable (Map k) where
foldr f z m = foldr f z (values m)
foldMap f m = foldMap f (values m)

instance traversableMap :: (Ord k) => Traversable (Map k) where
instance traversableMap :: Ord k => Traversable (Map k) where
traverse f ms = foldr (\x acc -> union <$> x <*> acc) (pure empty) ((map (uncurry singleton)) <$> (traverse f <$> toList ms))
sequence = traverse id

Expand Down Expand Up @@ -368,17 +368,17 @@ fromFoldableWith f = foldl (\m (Tuple k v) -> alter (combine v) k m) empty where
-- | Convert a map to a list of key/value pairs
toList :: forall k v. Map k v -> List (Tuple k v)
toList Leaf = Nil
toList (Two left k v right) = toList left <> pure (Tuple k v) <> toList right
toList (Three left k1 v1 mid k2 v2 right) = toList left <> pure (Tuple k1 v1) <> toList mid <> pure (Tuple k2 v2) <> toList right

-- | Create a map from a list of key/value pairs
fromList :: forall k v. Ord k => List (Tuple k v) -> Map k v
fromList = fromFoldable
toList (Two left k v right) = toList left <> Tuple k v : toList right
toList (Three left k1 v1 mid k2 v2 right) = toList left <> Tuple k1 v1 : toList mid <> Tuple k2 v2 : toList right

-- | Create a map from a list of key/value pairs, using the specified function
-- | to combine values for duplicate keys.
fromListWith :: forall k v. Ord k => (v -> v -> v) -> List (Tuple k v) -> Map k v
fromListWith = fromFoldableWith
-- | Convert a map to an unfoldable structure of key/value pairs
toUnfoldable :: forall f k v. (Ord k, Unfoldable f) => Map k v -> f (Tuple k v)
toUnfoldable = unfoldr go
where
go :: Map k v -> Maybe (Tuple (Tuple k v) (Map k v))
go Leaf = Nothing
go (Two left k v right) = Just $ Tuple (Tuple k v) (left <> right)
go (Three left k1 v1 mid k2 v2 right) = Just $ Tuple (Tuple k1 v1) (Two left k2 v2 right)

-- | Get a list of the keys contained in a map
keys :: forall k v. Map k v -> List k
Expand Down
22 changes: 7 additions & 15 deletions src/Data/StrMap.purs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ module Data.StrMap
, insert
, lookup
, toList
, toUnfoldable
, fromFoldable
, fromFoldableWith
, fromList
, fromListWith
, delete
, pop
, member
Expand Down Expand Up @@ -51,6 +50,7 @@ import Data.Monoid (class Monoid, mempty)
import Data.StrMap.ST as SM
import Data.Traversable (class Traversable, traverse)
import Data.Tuple (Tuple(..), uncurry)
import Data.Unfoldable (class Unfoldable)

-- | `StrMap a` represents a map from `String`s to values of type `a`.
foreign import data StrMap :: * -> *
Expand Down Expand Up @@ -191,8 +191,7 @@ update :: forall a. (a -> Maybe a) -> String -> StrMap a -> StrMap a
update f k m = alter (maybe Nothing f) k m

-- | Create a map from a foldable collection of key/value pairs
fromFoldable :: forall f a. (Foldable f) =>
f (Tuple String a) -> StrMap a
fromFoldable :: forall f a. Foldable f => f (Tuple String a) -> StrMap a
fromFoldable l = pureST (do
s <- SM.new
for_ l (\(Tuple k v) -> SM.poke s k v)
Expand All @@ -202,28 +201,21 @@ foreign import _lookupST :: forall a h r z. Fn4 z (a -> z) String (SM.STStrMap h

-- | Create a map from a foldable collection of key/value pairs, using the
-- | specified function to combine values for duplicate keys.
fromFoldableWith :: forall f a. (Foldable f) =>
(a -> a -> a) -> f (Tuple String a) -> StrMap a
fromFoldableWith :: forall f a. Foldable f => (a -> a -> a) -> f (Tuple String a) -> StrMap a
fromFoldableWith f l = pureST (do
s <- SM.new
for_ l (\(Tuple k v) -> runFn4 _lookupST v (f v) k s >>= SM.poke s k)
pure s)

-- | Create a map from a list of key/value pairs
fromList :: forall a. L.List (Tuple String a) -> StrMap a
fromList = fromFoldable

-- | Create a map from a list of key/value pairs, using the specified function
-- | to combine values for duplicate keys.
fromListWith :: forall a. (a -> a -> a) -> L.List (Tuple String a) -> StrMap a
fromListWith = fromFoldableWith

foreign import _collect :: forall a b . (String -> a -> b) -> StrMap a -> Array b

-- | Convert a map into a list of key/value pairs
toList :: forall a. StrMap a -> L.List (Tuple String a)
toList = L.fromFoldable <<< _collect Tuple

toUnfoldable :: forall f a. Unfoldable f => StrMap a -> f (Tuple String a)
toUnfoldable = L.toUnfoldable <<< toList

-- | Get an array of the keys in a map
foreign import keys :: forall a. StrMap a -> Array String

Expand Down
27 changes: 14 additions & 13 deletions test/Test/Data/Map.purs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@ import Control.Monad.Eff.Random (RANDOM)
import Data.Foldable (foldl, for_, all)
import Data.Function (on)
import Data.List (List(..), groupBy, length, nubBy, sortBy, singleton)
import Data.List.NonEmpty as NEL
import Data.Map as M
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Tuple (Tuple(..), fst)

import Partial.Unsafe (unsafePartial)

import Test.QuickCheck ((<?>), quickCheck, quickCheck')
import Test.QuickCheck ((<?>), (===), quickCheck, quickCheck')
import Test.QuickCheck.Arbitrary (class Arbitrary, arbitrary)

newtype TestMap k v = TestMap (M.Map k v)

instance arbTestMap :: (Eq k, Ord k, Arbitrary k, Arbitrary v) => Arbitrary (TestMap k v) where
arbitrary = TestMap <<< M.fromList <$> arbitrary
arbitrary = TestMap <<< (M.fromFoldable :: List (Tuple k v) -> M.Map k v) <$> arbitrary

data SmallKey = A | B | C | D | E | F | G | H | I | J

Expand Down Expand Up @@ -193,25 +194,25 @@ mapTests = do
quickCheck (M.lookup 1 nums == Just 2 <?> "invalid lookup - 1")
quickCheck (M.lookup 2 nums == Nothing <?> "invalid lookup - 2")

log "toList . fromList = id"
quickCheck $ \arr -> let f x = M.toList (M.fromList x)
log "toList . fromFoldable = id"
quickCheck $ \arr -> let f x = M.toList (M.fromFoldable x)
in f (f arr) == f (arr :: List (Tuple SmallKey Int)) <?> show arr

log "fromList . toList = id"
quickCheck $ \(TestMap m) -> let f m' = M.fromList (M.toList m') in
log "fromFoldable . toList = id"
quickCheck $ \(TestMap m) -> let f m' = M.fromFoldable (M.toList m') in
M.toList (f m) == M.toList (m :: M.Map SmallKey Int) <?> show m

log "fromListWith const = fromList"
quickCheck $ \arr -> M.fromListWith const arr ==
M.fromList (arr :: List (Tuple SmallKey Int)) <?> show arr
log "fromFoldableWith const = fromFoldable"
quickCheck $ \arr -> M.fromFoldableWith const arr ==
M.fromFoldable (arr :: List (Tuple SmallKey Int)) <?> show arr

log "fromListWith (<>) = fromList . collapse with (<>) . group on fst"
log "fromFoldableWith (<>) = fromFoldable . collapse with (<>) . group on fst"
quickCheck $ \arr ->
let combine (Tuple s a) (Tuple t b) = (Tuple s $ b <> a)
foldl1 g = unsafePartial \(Cons x xs) -> foldl g x xs
f = M.fromList <<< map (foldl1 combine) <<<
f = M.fromFoldable <<< map (foldl1 combine <<< NEL.toList) <<<
groupBy ((==) `on` fst) <<< sortBy (compare `on` fst) in
M.fromListWith (<>) arr == f (arr :: List (Tuple String String)) <?> show arr
M.fromFoldableWith (<>) arr === f (arr :: List (Tuple String String))

log "Lookup from union"
quickCheck $ \(TestMap m1) (TestMap m2) k ->
Expand Down Expand Up @@ -249,7 +250,7 @@ mapTests = do
log "size"
quickCheck $ \xs ->
let xs' = nubBy ((==) `on` fst) xs
in M.size (M.fromList xs') == length (xs' :: List (Tuple SmallKey Int))
in M.size (M.fromFoldable xs') == length (xs' :: List (Tuple SmallKey Int))

log "lookupLE result is correct"
quickCheck $ \k (TestMap m) -> case M.lookupLE k (smallKeyToNumberMap m) of
Expand Down
23 changes: 12 additions & 11 deletions test/Test/Data/StrMap.purs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Control.Monad.Eff.Random (RANDOM)
import Data.Foldable (foldl)
import Data.Function (on)
import Data.List (List(..), groupBy, sortBy, singleton, fromFoldable, zipWith)
import Data.List.NonEmpty as NEL
import Data.Maybe (Maybe(..))
import Data.StrMap as M
import Data.Tuple (Tuple(..), fst)
Expand All @@ -22,7 +23,7 @@ import Test.QuickCheck.Arbitrary (class Arbitrary, arbitrary)
newtype TestStrMap v = TestStrMap (M.StrMap v)

instance arbTestStrMap :: (Arbitrary v) => Arbitrary (TestStrMap v) where
arbitrary = TestStrMap <<< M.fromList <$> arbitrary
arbitrary = TestStrMap <<< (M.fromFoldable :: List (Tuple String v) -> M.StrMap v) <$> arbitrary

data Instruction k v = Insert k v | Delete k

Expand Down Expand Up @@ -118,26 +119,26 @@ strMapTests = do
quickCheck (M.lookup "1" nums == Just 2 <?> "invalid lookup - 1")
quickCheck (M.lookup "2" nums == Nothing <?> "invalid lookup - 2")

log "fromFoldable . fromList = id"
quickCheck $ \arr -> let f x = M.toList (M.fromList x)
log "toList . fromFoldable = id"
quickCheck $ \arr -> let f x = M.toList (M.fromFoldable x)
in f (f arr) == f (arr :: List (Tuple String Int)) <?> show arr

log "fromList . fromFoldable = id"
log "fromFoldable . toList = id"
quickCheck $ \(TestStrMap m) ->
let f m1 = M.fromList (M.toList m1) in
let f m1 = M.fromFoldable (M.toList m1) in
M.toList (f m) == M.toList (m :: M.StrMap Int) <?> show m

log "fromListWith const = fromList"
quickCheck $ \arr -> M.fromListWith const arr ==
M.fromList (arr :: List (Tuple String Int)) <?> show arr
log "fromFoldableWith const = fromFoldable"
quickCheck $ \arr -> M.fromFoldableWith const arr ==
M.fromFoldable (arr :: List (Tuple String Int)) <?> show arr

log "fromListWith (<>) = fromList . collapse with (<>) . group on fst"
log "fromFoldableWith (<>) = fromFoldable . collapse with (<>) . group on fst"
quickCheck $ \arr ->
let combine (Tuple s a) (Tuple t b) = (Tuple s $ b <> a)
foldl1 g = unsafePartial \(Cons x xs) -> foldl g x xs
f = M.fromList <<< map (foldl1 combine) <<<
f = M.fromFoldable <<< map (foldl1 combine <<< NEL.toList) <<<
groupBy ((==) `on` fst) <<< sortBy (compare `on` fst) in
M.fromListWith (<>) arr == f (arr :: List (Tuple String String)) <?> show arr
M.fromFoldableWith (<>) arr == f (arr :: List (Tuple String String)) <?> show arr

log "Lookup from union"
quickCheck $ \(TestStrMap m1) (TestStrMap m2) k ->
Expand Down