hset-2.0.0: src/Data/HSet/Remove.hs
module Data.HSet.Remove
( HRemove(..)
, HDeletable
, hdelete
) where
import Data.HSet.Type
import Data.HSet.TypeLevel
import Data.Typeable
#if !(MIN_VERSION_base(4, 8, 0))
import Control.Applicative
#endif
-- | Remove i's element from hset. Second argument is a resulting hset
-- type
class HRemove els1 els2 i | els1 i -> els2 where
hremove :: Proxy i -> HSet els1 -> HSet els2
instance HRemove (e ': els) els 'Z where
hremove _ (HSCons _ els) = els
instance ( 'False ~ (Elem e els2)
, HRemove els1 els2 i )
=> HRemove (e ': els1) (e ': els2) ('S i) where
hremove _ (HSCons e els) = HSCons e $ hremove (Proxy :: Proxy i) els
{- | Delete element from HSet of specified type
>>> let x = (HSCons "sdf" $ HSCons 123 HSNil) :: HSet '[String, Int]
>>> hdelete (Proxy :: Proxy Int) x
HSCons ("sdf") (HSNil)
>>> hdelete (Proxy :: Proxy String) x
HSCons (123) (HSNil)
-}
-- | Constraints that e can be removed from els1 and els2 will be
-- produced in result
type HDeletable e els1 els2 = HRemove els1 els2 (Index e els1)
-- | Delete specific element from els1 and returns HSet with els2
hdelete :: forall proxy els1 els2 e
. (HDeletable e els1 els2)
=> proxy e
-> HSet els1
-> HSet els2
hdelete _ h = hremove (Proxy :: Proxy (Index e els1)) h