----------------------------------------------------------------------------- -- | -- Module : Data.OrdSets -- 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 -- Rory Z, rory@emqx.io -- Stability : experimental -- Portability : portable -- -- The Ordered Set datatype. -- ----------------------------------------------------------------------------- module Data.OrdSets where import Foreign (ffi0, ffi1, ffi2) import Test.QuickCheck (arbitrary, class Arbitrary) import Control.Monad ((<$>), liftA1) import Data.Show (class Show, show) import Data.Read (class Read, read) import Data.Eq (class Eq, eq) import Data.Ord (class Ord, compare) 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 OrdSet :: Type -> Type instance Show a => Show (OrdSet a) where show x = show (toList x) instance Read a => Read (OrdSet a) where read x = fromList (read x) instance Eq a => Eq (OrdSet a) where eq x y = eq (toList x) (toList y) instance Ord a => Ord (OrdSet a) where compare x y = compare (toList x) (toList y) instance Arbitrary v => Arbitrary (OrdSet v) where arbitrary = fromList <$> arbitrary instance Semigroup (OrdSet a) where append = union instance Monoid (OrdSet a) where mempty = new instance Functor OrdSet where map f x = fromList (map f (toList x)) instance Foldable OrdSet where foldl f init x = foldl f init (toList x) foldr f init x = foldr f init (toList x) foldMap f = foldr (\x acc -> f x <> acc) mempty instance Traversable OrdSet where traverse f ta = sequence (f <$> ta) sequence x = liftA1 fromList (sequence (toList x)) new :: forall a. OrdSet a new = ffi0 :ordsets :new add :: forall a.a -> OrdSet a -> OrdSet a add = ffi2 :ordsets :add_element del :: forall a.a -> OrdSet a -> OrdSet a del = ffi2 :ordsets :del_element filter :: forall a. (a -> Boolean) -> OrdSet a -> OrdSet a filter = ffi2 :ordsets :filter foreign import fold :: forall a acc. (a -> acc -> acc) -> acc -> OrdSet a -> acc intersectionFromList :: forall a. [a] -> OrdSet a intersectionFromList = ffi1 :ordsets :intersection intersection :: forall a. OrdSet a -> OrdSet a -> OrdSet a intersection = ffi2 :ordsets :intersection fromList :: forall a. [a] -> OrdSet a fromList = ffi1 :ordsets :from_list isDisjoint :: forall a. OrdSet a -> OrdSet a -> Boolean isDisjoint = ffi2 :ordsets :is_disjoint isElement :: forall a. a -> OrdSet a -> Boolean isElement = ffi2 :ordsets :is_element isSet :: forall a. a -> Boolean isSet = ffi1 :ordsets :is_set isSubset :: forall a. OrdSet a -> OrdSet a -> Boolean isSubset = ffi2 :ordsets :is_subset size :: forall a. OrdSet a -> Integer size = ffi1 :ordsets :size subtract :: forall a. OrdSet a -> OrdSet a -> OrdSet a subtract = ffi2 :ordsets :subtract toList :: forall a. OrdSet a -> [a] toList = ffi1 :ordsets :to_list unionFromList :: forall a. [a] -> OrdSet a unionFromList = ffi1 :ordsets :union union :: forall a. OrdSet a -> OrdSet a -> OrdSet a union = ffi2 :ordsets :union