Current section
Files
Jump to
Current section
Files
lib/Data/Map.hm
-----------------------------------------------------------------------------
-- |
-- Module : Data.Map
-- Copyright : (c) 2020-2021 EMQ Technologies Co., Ltd.
-- License : BSD-style (see the LICENSE file)
--
-- Maintainer : Feng Lee, feng@emqx.io
-- Yang M, yangm@emqx.io
-- Stability : experimental
-- Portability : portable
--
-- The Map datatype.
--
-----------------------------------------------------------------------------
module Data.Map where
import Data.Maybe (Maybe)
import Control.Monad ((<$>), liftA1)
import Foreign (ffi0, ffi1, ffi2, ffi3, ffi4)
import Test.QuickCheck (arbitrary, class Arbitrary)
import Data.Eq (class Eq)
import Data.Ord (class Ord, compare)
import Data.Show (class Show, show)
import Data.Read (class Read, read)
import Data.Semigroup (class Semigroup, (<>))
import Data.Monoid (class Monoid, mempty)
import Data.Functor (class Functor, map)
import Data.Foldable (class Foldable, foldl, foldr)
import Data.Traversable (class Traversable, sequence)
foreign import data Map :: Type -> Type -> Type
instance (Show a, Show b) => Show (Map a b) where
show x = show (toList x)
instance (Read a, Read b) => Read (Map a b) where
read x = fromList (read x)
instance (Ord a, Ord b) => Ord (Map a b) where
compare x y = compare (toList x) (toList y)
instance (Arbitrary k, Arbitrary v) => Arbitrary (Map k v) where
arbitrary = fromList <$> arbitrary
instance Eq (Map a b) where
eq = eqMapImpl
instance Functor (Map k) where
map f x = fromList (map (\(k, v) -> (k, f v)) (toList x))
instance Foldable (Map k) where
foldl f init x = foldl (\acc (k, v) -> f acc v) init (toList x)
foldr f init x = foldr (\(k, v) acc -> f v acc) init (toList x)
foldMap f = foldr (\x acc -> f x <> acc) mempty
instance Traversable (Map k) where
traverse f ta = sequence (f <$> ta)
sequence x = liftA1 fromList (sequence (map lifting (toList x)))
where lifting (k, v) = liftA1 (\a -> (k, a)) v
foreign import eqMapImpl :: forall a b. Map a b -> Map a b -> Boolean
instance Semigroup (Map a b) where
append = merge
instance Monoid (Map a b) where
mempty = empty
-- | Returns a new empty map.
empty :: forall k v. Map k v
empty = ffi0 :maps :new
-- | Create a map with only one key-value pair.
foreign import singleton :: forall k v. k -> v -> Map k v
-- | Test if the map is empty.
foreign import isEmpty :: forall k v. Map k v -> Boolean
-- | Test if the Key exists in the Map.
isKey :: forall k v. k -> Map k v -> Boolean
isKey = ffi2 :maps :is_key
-- | Same to `put` function.
insert :: forall k v. k -> v -> Map k v -> Map k v
insert = put
-- | Insert the key-value pair into a map.
put :: forall k v. k -> v -> Map k v -> Map k v
put = ffi3 :maps :put
-- | Return the `Value` associated with `Key`. Throw exception if the `Key` does not exist.
get :: forall k v. k -> Map k v -> v
get = ffi2 :maps :get
-- | Return the `Value` associated with `Key`.
foreign import lookup :: forall k v. k -> Map k v -> Maybe v
-- | TODO: docs later...
foreign import mapWithKey :: forall k v. ((k, v) -> v) -> Map k v -> Map k v
-- map = ffi2 :maps :map
-- | Test if a key is a member of a Map.
member :: forall k v. k -> Map k v -> Boolean
member = ffi2 :maps :is_key
-- | Test if a key is not a member of a Map.
foreign import notMember :: forall k v. k -> Map k v -> Boolean
fold :: forall k v acc. ((k, v, acc) -> acc) -> acc -> Map k v -> acc
fold = ffi3 :maps :fold
-- | Update an existed key-value pair.
update :: forall k v. k -> v -> Map k v -> Map k v
update = ffi3 :maps :update
-- | Update a value in a Map1 associated with Key by calling Fun on the old value to get a new value.
updateWith :: forall k v. k -> (v -> v) -> Map k v -> Map k v
updateWith = ffi3 :maps :update_with
updateWithInit :: forall k v. k -> (v -> v) -> v -> Map k v -> Map k v
updateWithInit = ffi4 :maps :update_with
-- | TODO: docs later...
foreign import take :: forall k v. k -> Map k v -> Maybe (v, (Map k v))
-- | Delete the key-value pair, if it exists.
delete :: forall k v. k -> Map k v -> Map k v
delete = ffi2 :maps :remove
-- | Returns the size of the Map.
size :: forall k v. Map k v -> Integer
size = ffi1 :maps :size
-- | Returns a map Map for which predicate Pred holds true in Map.
foreign import filter :: forall k v. ((k, v) -> Boolean) -> Map k v -> Map k v
-- | Merges two maps into a single map.
merge :: forall k v. Map k v -> Map k v -> Map k v
merge = ffi2 :maps :merge
-- | An alias of `toList` function.
assocs :: forall k v. Map k v -> [(k,v)]
assocs = toList
-- | Returns a list of keys contained in a map.
keys :: forall k v. Map k v -> List k
keys = ffi1 :maps :keys
-- | Returns a list of values contained in a map.
values :: forall k v. Map k v -> List v
values = ffi1 :maps :values
-- | Builds a map from a list of key-value tuples.
fromList :: forall k v. [(k,v)] -> Map k v
fromList = ffi1 :maps :from_list
-- | Returns a list of pairs representing the key-value associations of Map.
toList :: forall k v. Map k v -> [(k,v)]
toList = ffi1 :maps :to_list
-- | TODO: docs later...
with :: forall k v. [k] -> Map k v -> Map k v
with = ffi2 :maps :with
-- | TODO: docs later...
without :: forall k v. [k] -> Map k v -> Map k v
without = ffi2 :maps :without
tzip :: forall a b. [a] -> [b] -> [(a,b)]
tzip x [] = []
tzip [] y = []
tzip [x|xs] [y|ys] = [ (x,y) | tzip xs ys ]