Skip to content

Commit

Permalink
Merge pull request #107 from serokell/vrom911/97-ToPairs
Browse files Browse the repository at this point in the history
[#97] Add ToPairs class
  • Loading branch information
chshersh authored Dec 29, 2017
2 parents d484c24 + e02eca8 commit 156eab5
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
4 changes: 3 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
=====

* [#91](https:/serokell/universum/issues/91):
Change argument order of foldl'
Change argument order of `foldl'`.
* [#97](https:/serokell/universum/issues/97):
Add `ToPairs` type class with the ability to have list of pairs.

1.0.1
=====
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ Finally, we can move to part describing the new cool features we bring with `uni
for creating singleton containers. Even monomorhpic ones like `Text`.
* `evaluateWHNF` and `evaluateNF` functions as clearer and lifted aliases for
`evaluate` and `evaluate . force`.
* `ToPairs` type class for data types that can be converted to list of pairs.

License
-------
Expand Down
80 changes: 79 additions & 1 deletion src/Universum/Container/Class.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
module Universum.Container.Class
( -- * Foldable-like classes and methods
ToList (..)
, ToPairs (..)
, Container (..)

, sum
Expand Down Expand Up @@ -94,7 +95,6 @@ type family ElementDefault (t :: *) :: * where
ElementDefault (f a) = a

-- | Type class for data types that can be converted to List.
-- Fully compatible with 'Foldable'.
-- Contains very small and safe subset of 'Foldable' functions.
--
-- You can define 'Tolist' by just defining 'toList' function.
Expand Down Expand Up @@ -204,6 +204,84 @@ instance ToList (Set v)
instance ToList (Seq a)
instance ToList (Vector a)

----------------------------------------------------------------------------
-- ToPairs
----------------------------------------------------------------------------

{- | Type class for data types that can be converted to List of Pairs.
You can define 'ToPairs' by just defining 'toPairs' function.
But the following laws should be met:
@
'toPairs' m ≡ 'zip' ('keys' m) ('elems' m)
'keys' ≡ 'map' 'fst' . 'toPairs'
'elems' ≡ 'map' 'snd' . 'toPairs'
@
-}
class ToPairs t where
{-# MINIMAL toPairs #-}
-- | Type of keys of the mapping.
type Key t :: *
-- | Type of value of the mapping.
type Val t :: *

-- | Converts the structure to the list of the key-value pairs.
-- >>> import qualified Data.HashMap as HashMap
-- >>> toPairs (HashMap.fromList [('a', "xxx"), ('b', "yyy")])
-- [('a', "xxx"), ('b', "yyy")]
toPairs :: t -> [(Key t, Val t)]

-- | Converts the structure to the list of the keys.
--
-- >>> keys (HashMap.fromList [('a', "xxx"), ('b', "yyy")])
-- "ab"
keys :: t -> [Key t]
keys = map fst . toPairs
{-# INLINE keys #-}

-- | Converts the structure to the list of the values.
--
-- >>> elems (HashMap.fromList [('a', "xxx"), ('b', "yyy")])
-- ["xxx", "yyy"]
elems :: t -> [Val t]
elems = map snd . toPairs
{-# INLINE elems #-}

-- Instances

instance ToPairs (HashMap k v) where
type Key (HashMap k v) = k
type Val (HashMap k v) = v
toPairs = HM.toList
{-# INLINE toPairs #-}
keys = HM.keys
{-# INLINE keys #-}
elems = HM.elems
{-# INLINE elems #-}

instance ToPairs (IntMap v) where
type Key (IntMap v) = Int
type Val (IntMap v) = v
toPairs = IM.toList
{-# INLINE toPairs #-}
keys = IM.keys
{-# INLINE keys #-}
elems = IM.elems
{-# INLINE elems #-}

instance ToPairs (Map k v) where
type Key (Map k v) = k
type Val (Map k v) = v
toPairs = M.toList
{-# INLINE toPairs #-}
keys = M.keys
{-# INLINE keys #-}
elems = M.elems
{-# INLINE elems #-}


----------------------------------------------------------------------------
-- Additional operations that don't make much sense for e.g. Maybe
----------------------------------------------------------------------------
Expand Down

0 comments on commit 156eab5

Please sign in to comment.